这是一个令人难以置信的简单应用程序:
<body ng-controller="MainCtrl">
<div parent ng-repeat="parent in parents">
<h1>{{ parent.family }} Family</h1>
<div child="parent.child">
Their kid's name is {{ child }}
</div>
</div>
</body>
使用以下app.js
:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.parents = [{
'child' : 'John',
'family': 'Johnson'
}, {
'child' : 'Jack',
'family': 'Jackson'
}, {
'child' : 'Jeff',
'family': 'Jefferson'
}];
});
app.directive('parent', function()
{
return {
restrict: 'AE'
}
});
app.directive('child', function()
{
return {
restrict: 'AE',
scope: {
child: '='
}
}
});
我期待看到三排“杰克逊家族。他们孩子的名字是杰克”等等。但是,由于child
上的隔离范围,这不起作用。相反,如果我将标记更改为
<div parent ng-repeat="parent in parents">
<h1>{{ parent.family }} Family</h1>
<div child="parent.child"></div>
</div>
然后在child
指令template: 'Their kid\'s name is {{ child }}'
添加额外的一行,然后就可以了。
以下是两种情景的关键词:
为什么?
答案 0 :(得分:2)
如果没有额外的工作,您可以在指令中使用transclude
选项,以便内容绑定到父作用域,但内容必须是:
Their kid's name is {{ parent.child }}
或者,您可以隔离范围(如您所做),但是范围需要应用于指令中定义的模板 - 您不想这样做。
修改强>
下面的$compile
- 方法(如最初编写的)是次优的,因为它会使内容编译和链接两次。正确(和更好)的方法是使用transclude
:
app.directive('child', function($compile)
{
return {
restrict: 'AE',
transclude: true,
scope: {
child: '='
},
link: function(scope, elem, attrs, ctrls, transclude){
transclude(scope, function(clone){
elem.append(clone);
});
}
}
});
已修改plunker
transclude
在编译child
指令时编译内容,但使编译的内容可用。通过调用transclude
函数,您可以将内容链接到指定的范围 - 这里是子指令的范围。
原始答案(不推荐)
要使您的示例工作 - 即使用指令的内容作为模板 - 您需要使用指令的范围对它们进行编译,如下所示:
app.directive('child', function($compile)
{
return {
restrict: 'AE',
scope: {
child: '='
},
link: function(scope, elem){
$compile(elem.contents())(scope));
}
}
});
这是您修改后的plunker。
答案 1 :(得分:0)
在第二种情况下,你已经过了
<div child="parent.child"></div>
您使用双向绑定将parent.child传递给指令
scope: {
child: '='
},
因此您可以在模板中使用子项
template: 'Their kid\'s name is {{ child }}'
在第一种情况下(有缺陷)你要重新招架孩子
Their kid's name is {{ child }}
但是孩子不存在你可以通过将其改为
来解决这个问题 Their kid's name is {{ parent.child }}