我有一个名为profile.html的可重用模板。它看起来像这样:
<div>
{{firstName}}
</div>
我将它嵌入另一个绑定到专用控制器的模板中:
<div ng-include src="'templates/profile.html'"></div>
我想为这个div创建一个子$ scope。在父模板的控制器中,我有类似的内容:
$scope.profile = theProfile;
我希望profile.html模板的子范围是父$ scope.profile。类似于:
<div ng-include src="'templates/profile.html'" ng-scope="{{profile}}"></div>
我该怎么做?
答案 0 :(得分:1)
看起来你基本上是通过尝试设置模板和范围来重新发明指令。此外,$ scope是一个对象,上面有大量其他属性/对象,因此将其设置为另一个对象会有问题。
如果您真的想这样做,下面将创建一个指令,使用角度副本将传入的profile
合并到$scope
。我建议只使用$ scope.profile。
.directive('profile', [function(){
return{
templateUrl:'templates/profile.html',
scope:{profile:'='},
controller: function($scope){
angular.copy($scope.profile, $scope) // if you really, really want the properties right on the scope.
}
}
}]
答案 1 :(得分:1)
ngInclude
会自动创建子范围。您不应该显式地将一些数据传递给它,因为它可以通过原型继承访问其父作用域(如果您的模板更改了作用域,这可能会成为一个问题)。
这里的问题是您的模板需要在范围内存在firstName
属性,但它并不存在。因此,您可以将模板更改为
<div>
{{profile.firstName}}
</div>
但是这会将模板耦合到profile
对象,这可能是一个坏主意。
另一种解决方案是在正确的范围内手动创建firstName
属性:
<div ng-include src="'templates/profile.html'"
ng-init="firstName=profile.firstName">
</div>
我不太喜欢这个解决方案,因为如果模板需要更多属性并且它在某种程度上打破了模板封装,它很容易失控。
最后,您可以将该模板包装在指令中:
directive('whateverMakesSense', function() {
return {
restrict: 'E',
template: '<div>{{data.firstName}}</div>',
scope: { data: '=' }
};
});
...
<whatever-makes-sense data="profile"></whatever-makes-sense>
如果您发现自己在很多地方使用该模板,我建议您选择自定义指令方法。它会给你更多的控制,事情会更好地封装,作为奖励你的标记会更加语义 - 当然,如果你使用whatever-makes-sense
以外的任何东西。 :)