[英]parent with child directives won't work when creating new scope
我创建了一个父指令,该指令可以从给定的URL检索数据,这很好。 第二步,我想在几个子指令之间分配数据,例如:
<parent data="some/url/with/json/response">
<child data="data[0]"></child>
<child data="data[1]"></child>
...
</parent>
这也很好。 但是,在创建另一组指令时,旧数据将被覆盖,因为父指令不会创建新的作用域,而是会覆盖主作用域中的所有内容。 当在指令中指定以下行之一时,根本不显示任何数据(现在出现错误msg):
scope: true,
//or
scope: {},
这是错误情况的一个笨拙的示例: http ://plnkr.co/edit/GWcLrhaUHNLPWNkOHIS8?p=preview顶部应显示“ This is working”。
因此,问题是:有谁知道我可以如何强制parent指令创建所有子元素都可以访问的新作用域?
在子指令中,应在父作用域上评估字符串,如下所示:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
app.directive('parentBindScope', function($timeout) {
return {
restrict: 'E',
transclude: true,
scope: true,
template: '<div ng-transclude></div>',
controller: function($scope, $attrs) {
if($attrs.working) {
$scope.working = {key: 'this is working'};
} else {
$scope.working = { key: 'something else' }
$timeout(function(){
$scope.working = {key: 'this is not working'};
},1000)
}
}
}
});
app.directive('childBindScope', function($parse) {
return {
restrict: 'E',
template: '<div>child-template: {{data}}</div>',
controller: function($scope, $attrs) {
$scope.$watch('$parent.' + $attrs.data, function() {
$scope.data = $scope.$parent.$eval($attrs.data);
});
},
link: function(scope, element, attrs) {
console.log('data: ' + JSON.stringify(scope.data));
}
}
})
采用:
scope: false
在您的子范围内 ,保留子元素中父元素的范围。
使用true或{}称为isolateScope,这是有原因的。 保护子范围。
问题在于父指令正在继承作用域(控制器的作用域),因此所有父指令本质上都共享同一作用域。 当父母双方共享同一个范围时,要执行的最后一个指令(不具有“ working”属性的父母指令)将在共享范围内定义“ working”属性,该属性在链接实现中分配$ scope.working =“ this不管用”。
<!-- bind object to child scope -->
<parent-bind-scope working=true>
Should be working:
<child-bind-scope data="working"></child-bind-scope>
</parent-bind-scope>
<br>
<parent-bind-scope>
Should not be working:
<child-bind-scope data="working"></child-bind-scope>
</parent-bind-scope>
如果在分配$ scope.working时发出警报,则可以看到它正在执行if条件的两个分支(else控制流位于最后):
controller: function($scope, $attrs) {
if($attrs.working) {
alert('working attribute exists');
$scope.working = {key: 'this is working'};
} else {
alert('working attribute does not exist');
$scope.working = {key: 'this is not working'};
}
}
我终于找到了一个看起来也不错的解决方案。 因为plunker默认情况下是通过使用angular 1.2创建脚本的,所以我没有较早找到此解决方案(显然它仅在1.3.x中有效)。 现在,每个父指令确实创建了自己的作用域,而子代也这样做。 然后,通过使用此表示法(带有$ parent),将显示正确的数据:
<parent-bind-scope working=true>
Should be working:
<child-bind-scope data="$parent.working"></child-bind-scope>
</parent-bind-scope>
另请参阅: http : //plnkr.co/edit/NkVxpjryD8YQm9xovw4M?p=preview
在使用Remco的答案并为孩子创建隔离范围时,我必须使用$ parent。$ parent来获得相同的结果,因此这是该解决方案的重要一步。
另外:使用ng-repeat时很奇怪,在我的真实代码中,我现在必须要做$ parent。$ parent。$ parent这样的工作:
//not the exact code
<parent parentdata="/url/with/data">
<div ng-repeat="i in $parent.range($parentdata.data.cols.length) track by $index">
<child data1="$parent.$parent.$parent.parentdata.cols[$index]"
data2="$parent.$parent.$parent.parentdata.rows[$index]"/>
</div>
</parent>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.