说明:
- angularJS中,ng-if,ng-repeat,ng-switch,ng-view,ng-include都会创建自己的子作用域,
这意味着原始类型的变量及对象将不能通过$scope被直接传值或调用;
其中ng-repeat还带有赋值行为; - angularJS遵循原生JS的原型继承机制,即如果我们在子作用域中访问一个父作用域中定义的属性,JS首先在子作用域中寻找该属性,没找到再从原型链上的父作用域中寻找,如果还没找到会再往上一级原型链的父作用域寻找.
- 所以被重新创建为子作用域的angular dom将不能被直接访问子属性.同理也不能被$scope所影响.
解决方案:
1. 使用ng-show/ng-hide替代部分ng-if的效果:
- ng-show与ng-hide本质上是通过控制css来实现dom的显示/隐藏,等同于
display:none;
或visibility:hidden;
; - 很多业务场景中,在页面上使用ng-if是为了控制dom的展现,这种情形下可以用ng-show替代;
- ng-show与ng-if不同,在页面被渲染完毕时ng-show中的内容已经静态化,而ng-if的每次true判定都将初始化作用域下的内容;
- 由上可得,ng-show中绑定的scope在页面渲染完成后就已经生效,是可以被直接使用的.
<div class="menu-item" ng-show="status === true">
<input type="text" name="option_input" ng-model="option" required>
</div>
console.log($scope.option);
2.在父作用域中定义一个父类对象:
- 官方文档中推荐使用此方法
避免这个问题的最佳实践是在ng-model中总使用.
; - 在父作用域中定义一个父类对象,在子作用域中scope其属性,
这样即使子作用域被重新创建,scope仍然可以通过搜寻原型链找到其父类对象,完成$scope操作;
$scope.opt = {};
<div class="menu-item" ng-if="status === true">
<input type="text" name="option_input" ng-model="opt.option" required>
</div>
console.log($scope.opt.option);
3.其它方案:
-
在子作用域中使用 $parent.parentScopeProperty,这样可以直接修改父作用域的属性.
-
在父作用域中定义函数,子作用域通过原型继承调用函数把值传递给父作用域(这种方式极少使用).
参考官方文档: http://www.angularjs.cn/A09C
网友评论