我有一个带隔离范围的指令,它通过引用获取范围变量
angular.module('myApp') .directive('myDirective',function() { return { scope: { items: '=' },templateUrl: 'template.html',replace: true,controller: 'myDirectiveCtrl',controllerAs: 'ctrl' }; }) .controller('myDirectiveCtrl',function($scope) { this.items = $scope.items; });
传递方式如下:
<div my-directive items='items'></div>
在外部控制器中,数据被异步加载,并且传递给指令的范围项更新:
angular.module('myApp',[]) .controller('myCtrl',function($scope) { $scope.setItems = function() { $scope.items = [ 'Here','There','Everywhere' ]; }; });
加载数据时,我的指令范围之外的范围会更新,但内部则不会
我的HTML:
<div my-directive items='items'></div> <!-- this doesn't update --> Outside directive <ul ng-repeat='i in items'> <!-- this does update --> <li>{{i}}</lu> </ul> <button ng-click="setItems()">Set items</button>
如何在我的指令中更新我的范围?我
当Angular首次运行你的指令的控制器函数时,$scope.items === undefined,所以当你这样做.items = $scope.items时,你的this.items ===也是未定义的.
而已.在那之后,没有什么可以改变这个.items.
这与$scope.items不同. $scope.items与外部作用域双向绑定,因此只要Angular在外部检测到更改,它就会设置隔离的作用域变量.
最简单的方法(在我看来最合适)是直接在指令中使用$scope属性:
<div> Inside directive <ul ng-repeat="i in items"> <li>{{ i }}</li> </ul> </div>
如果你想将你的控制器用作viewmodel而不是范围(我不知道你为什么会这样做),你可以这样做:
$scope.$watchCollection("items",function(newVal,oldVal) { ctrl.items = newVal; });
编辑:
在Angular 1.3中,您还可以在指令的定义中执行bindToController:true,以便控制器属性“items”将获得$scope.items获得的双向绑定.然后,你甚至不需要这样做.items = $scope.items;:
你的forked plunker来说明.