前两天想用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 也产生隔离作用域,但是大多数指令应该都会产生私有作用域。
这些都是新人实验结果,如有错误,烦请指正。