標籤:變數 標準 作用 預設 amp ack 雙向資料繫結 gem model
每當一個指令被建立的時候,都會有這樣一個選擇:是繼承自己的父範圍(一般是外部的Controller提供的範圍或者根範圍($rootScope)),還是建立一個新的自己的範圍。AngularJS為指令的scope參數提供了三種選擇,分別是:false,true,{}。
scope = false(預設情況)
當scope參數為false時,指令模板可以直接使用父範圍中的變數,函數。
代碼如下所示:
angular.module("MyApp", []).controller("MyController", function ($scope) { $scope.name = "dreamapple"; $scope.age = 20; $scope.changeAge = function () { $scope.age = 22; }}).directive("myDirective", function () { var obj = { restrict: "AE", scope: false, replace: true, template: "<div class=‘my-directive‘>" + "<h3>下面部分是我們建立的指令產生的</h3>" + "我的名字是:<span ng-bind=‘name‘></span><br/>" + "我的年齡是:<span ng-bind=‘age‘></span>" + "<input type=‘text‘ ng-model=‘name‘>"+ " </div>" } return obj;});
HTML代碼:
<div ng-app="MyApp"> <div class="container" ng-controller="MyController"> <div class="my-info">我的名字是:<span ng-bind="name"></span> <br/>我的年齡是:<span ng-bind="age"></span> </div> <div class="my-directive" my-directive></div> </div></div>
CSS代碼:
div{ padding: 6px;}div.container { border: 1px solid black;}div.my-info { border: 1px solid blue;}div.my-directive{ border: 1px solid green;}
因為我們將scope的屬性設定為false,所以我們建立的指令繼承了父範圍的一切屬性和方法,這也使得在指令的模板中我們可以使用這些屬性和方法。
-注意-:此時我們在輸入框裡改變名字,會發現上面的兩個名字都發生了變化。
scope = true
當把scope屬性設定為true時,這表明我們建立的指令要建立一個新的範圍,這個範圍初始化的時候繼承父範圍。修改建立的範圍內的值,只會改變該範圍下的資料。
修改上面的JS代碼,將指令中的:scope:false修改為scope:true試試效果
scope = {}
當我們將scope設定為{}時,意味著我們建立了一個新的與父範圍隔離的範圍,這使我們在不知道外部環境的情況下,就可以正常工作,不依賴外部環境。
修改上述的JS代碼和HTML代碼 JS代碼:
angular.module("MyApp", []).controller("MyController", function ($scope) { $scope.name = "dreamapple"; $scope.age = 20; $scope.changeAge = function(){ $scope.age = 0; }}).directive("myDirective", function () { var obj = { restrict: "AE", scope: { name: ‘@myName‘, age: ‘=‘, changeAge: ‘&changeMyAge‘ }, replace: true, template: "<div class=‘my-directive‘>" + "<h3>下面部分是我們建立的指令產生的</h3>" + "我的名字是:<span ng-bind=‘name‘></span><br/>" + "我的年齡是:<span ng-bind=‘age‘></span><br/>" + "在這裡修改名字:<input type=‘text‘ ng-model=‘name‘><br/>" + "<button ng-click=‘changeAge()‘>修改年齡</button>" + " </div>" } return obj;});
HTML代碼:
<div ng-app="MyApp"> <div class="container" ng-controller="MyController"> <div class="my-info">我的名字是:<span ng-bind="name"></span> <br/>我的年齡是:<span ng-bind="age"></span> <br /> </div> <div class="my-directive" my-directive my-name="{{name}}" age="age" change-my-age="changeAge()"></div> </div></div>
我們使用了隔離的範圍,不代表我們不可以使用父範圍的屬性和方法。
我們可以通過向scope的{}中傳入特殊的首碼標識符(即prefix),來進行資料的綁定。
在隔離範圍內,我們可以通過@,&和=引用應用指令的元素的屬性,如上面的代碼那樣,我們可以在<div class="my-directive" my-directive my-name="{{name}}" age="age" change-my-age="changeAge()"></div>這個元素中,利用首碼標識符通過使用屬性my-name,age,change-my-age來引用這些屬性的值。
下面我們來看看如何使用這些首碼標識符:
@
這是一個單項綁定的首碼標識符
使用方法:在元素中使用屬性,好比這樣<div my-directive my-name="{{name}}"></div>注意,屬性的名字要用-將兩個單詞串連,因為是資料的單項綁定所以要通過使用{{}}來綁定資料。
=
這是一個雙向資料繫結首碼標識符
使用方法:在元素中使用屬性,好比這樣<div my-directive age="age"></div>注意,資料的雙向繫結要通過=首碼標識符實現,所以不可以使用{{}}。
&
這是一個綁定函數方法的首碼標識符
使用方法:在元素中使用屬性,好比這樣<div my-directive change-my-age="changeAge()"></div>注意,屬性的名字要用-將多個個單詞串連。
-注意-:在新建立指令的範圍對象中,使用屬性的名字進行綁定時,要使用駝峰命名標準,比如下面的代碼。
scope: { name: ‘@myName‘, age: ‘=‘, changeAge: ‘&changeMyAge‘ }進一步說明,我們的指令是如何利用這些首碼標識符來尋找我們想要的屬性或者函數的?
@ 當指令編譯到模板的name時,就會到scope中尋找是否含有name的索引值對,如果存在,就像上面那樣,看到@就知道這是一個單向的資料繫結,然後尋找原來的那個使用指令的元素上(或者是指令元素本身)含有這個值的屬性即my-name={{name}},然後在父範圍尋找{{name}}的值,得到之後傳遞給模板中的name。
=和&與@差不多,只不過=進行的是雙向的資料繫結,不論模板還是父範圍上的屬性的值發生改變都會使另一個值發生改變,而&是綁定函數而已。
AngularJS 指令的 Scope (範圍)