前兩天想用ng-init做條件判斷的橋樑時出現了一次失敗,做了一個測試,發現angular的局部作用域影響ng-init定義的值。
ng-init的作用就是創建一個變量(bb)
一般情況下,和$scope.bb的作用一樣,不同的是,ngInit是指令,有局部作用域,改寫後顯得優先級更高。
可以理解爲在ngInit的作用域 $ngInitScope內又定義了一個 $ngInitScope.bb = $ngInitScope.website1,而且是雙向綁定
<div ng-init="bb=website1" ng-controller="Ctrl" >{{bb}}<div> //顯示11111
app.controller('Ctrl', ['$scope', function($scope) {
$scope.website1 = '11111';
$scope.bb = 'bbbbbbb';
console.log($scope.bb) //bbbbbb
})
這引出了angular作用域的問題。
經測試,覺得angular的作用域和函數(及代碼塊)的作用域很類似。每個指令在使用時,所在位置猶如函數聲明代碼塊的開始位置,以所附庸元素結尾(如)爲代碼塊的結束位置。
angular每個指令都意味着可以有獨立的作用域,如果指令包含其他的指令,則作用域也無限往局部縮小,就像函數內又聲明瞭函數。
同一個變量的值,在平級指令結構會是最後一次賦值的結果;在父子級結構裏,在各自的局部作用域有效
來看平級結構
<div ng-controller="Ctrl">
第一組
<div ng-init='aa1=website1'>
aa1:<div ng-bind="aa1"></div>
</div>
<div>
改變aa1:<input type="text" ng-model="aa1" />
<div ng-bind="aa1"></div>
</div >
<br />
第二組
<div ng-init='aa1=website5'>
aa1:<div ng-bind="aa1"></div>
</div>
<div>
改變aa1:<input type="text" ng-model="aa1" />
<div ng-bind="aa1"></div>
</div >
</div>
app .controller('Ctrl', ['$scope', function($scope) {
$scope.website1 = '11111';
$scope.website5 = '';
}])
顯示
aa全部被第二次賦值給蓋住了,因此得出結論:同級作用域,ngInit同名變量無限賦值,最終值爲最後一次賦值的結果,且與controller雙向綁定
如果有疑問,來修改平級第一個位置的輸入框更改aa1的值會發現全部一致變動
測試ngRepeat作用域
<div ng-controller="Ctrl">
第一組(ng-repeat)
<div ng-repeat="x in websitex track by $index" ng-if="$index==0">
<div ng-init="aa1 = x">
aa{{$index+1}}:<div ng-bind="aa1"></div>
</div>
<div>
改變aa1:<input type="text" ng-model="aa1" />
<div ng-bind="aa1"></div>
</div >
</div>
<br />
第二組(ng-repeat)
<div ng-repeat="x in websitey track by $index" ng-if="$index==0">
<div ng-init='aa1 = x'>
aa{{$index+1}}:<div ng-bind="aa1"></div>
</div>
<div>
改變aa1:<input type="text" ng-model="aa1" />
<div ng-bind="aa1"></div>
</div >
</div>
</div>
app .controller('Ctrl', ['$scope', function($scope) {
$scope.website1 = '11111';
$scope.website2 = '22222';
$scope.website3 = '33333';
$scope.website4 = '44444';
$scope.website5 = '';
$scope.website6 = '';
$scope.website7 = '';
$scope.website8 = '';
$scope.websitex = [$scope.website1,$scope.website2,$scope.website3,$scope.website4];
$scope.websitey = [$scope.website5,$scope.website6,$scope.website7,$scope.website8];
}])
只顯示aa1的值,顯示結果
ng-repeat作用域內ngInit分配的值只在該作用域內有效
現在測試ng-repeat內ngInit與同級ngInit同時存在時,同名變量的賦值情況
<div ng-controller="Ctrl" >
第一組(ng-repeat)
<div ng-repeat="x in websitex track by $index" ng-if="$index==0">
<div ng-init="aa1= x">
aa{{$index+1}}:<div ng-bind="aa1"></div>
<div>
改變aa1:<input type="text" ng-model="aa1"/>
<div ng-bind="aa1"></div>
</div >
</div>
</div>
<br />
ng-repeat外與ng-repeat平級
<div>
改變aa1:<input type="text" ng-model="aa1"/>
<div ng-bind="aa1"></div>
</div >
<br />
第二組(ng-repeat)
<div ng-repeat="x in websitey track by $index" ng-if="$index==0">
<div ng-init='aa1=x'>
aa{{$index+1}}:<div ng-bind="aa1"></div>
</div>
</div>
<br />
ng-repeat外與ng-repeat平級
<div>
改變aa1:<input type="text" ng-model="aa1" />
<div ng-bind="aa1"></div>
</div >
<br />
</div >
app.controller('Ctrl', ['$scope',function($scope) {
$scope.nowItem = ['', 'website', 'picSite', 'audio', 'video'];
$scope.website1 = '11111';
$scope.website2 = '22222';
$scope.website3 = '33333';
$scope.website4 = '44444';
$scope.website9 = '55555';
$scope.website5 = '';
$scope.website6 = '';
$scope.website7 = '';
$scope.website8 = '';
$scope.websitex = [$scope.website1,$scope.website2,$scope.website3,$scope.website4];
$scope.websitey = [$scope.website5,$scope.website6,$scope.website7,$scope.website8];
$scope.aa1 = 'aaaaaa';
}])
顯示結果爲
說明平級取的$scope作用域的值,ngRepeat取的是內部作用域的值
修改平級的值隻影響平級的值
修改ngRepeat內部也隻影響內部的值,說明應該是私有的作用域。
ngInit之所雙綁是因爲是可賦值的指令,之前寫項目發現 ngIf 也產生隔離作用域,但是大多數指令應該都會產生私有作用域。
這些都是新人實驗結果,如有錯誤,煩請指正。