截至下一个稳定的AngularJS发布时,我正在将我的应用程序从 1.0.8 迁移到 1.2 。
在AngularJS 1.0.8 中,可以为follow
等指令设置隔离范围。然后该指令将使用自己的test()
函数而不是控制器的test()
函数。
<my-dialog property="something">
<button ng-click="test()">Load Test</button>
Check out the test: "{{ testMessage }}"
</my-dialog>
.controller('Ctrl', function(scope) {
scope.test = function () {
scope.testMessage = 'CTRL Test loaded! Whooops.';
}
})
.directive('myDialog', function() {
return {
restrict: 'E',
scope: {
property: '='
},
link: function(scope) {
scope.test = function () {
scope.testMessage = 'Isolated Test loaded. Yes!';
}
}
};
在AngularJS 1.2 中,此行为不再有效。单击该按钮立即激活控制器的test()
功能。
请参阅此jsFiddle比较:
究竟有什么变化,我如何重现旧行为?
我发现我可以将指令模板放在一个额外的HTML文件中,或者将其编译为字符串以使其正常工作(jsFiddle)但是在我的情况下似乎太多了,因为模板已修复并将HTML分成几个部分HTML文件是一件麻烦事。
@elclanr's answer正常工作。我更新了the jsFiddle以传递一些任意属性。我现在该怎么办?
答案 0 :(得分:5)
看起来这是突破性变化的预期结果:github.com/angular/angular.js/commit/…这是在1.2.0(在rc3之后)(https://github.com/angular/angular.js/blob/master/CHANGELOG.md - 中拉出来的 - 看到1.2.0的第一次突破性变化 - $编译):
修复了隔离范围泄漏到同一元素上的其他指令的问题。
隔离范围现在仅适用于请求它及其模板的isolate指令。
非隔离指令不应该在同一元素上获取isolate指令的isolate范围,而是接收原始范围(这是新创建的隔离范围的父范围)。
另请参阅此讨论:github.com/angular/angular.js/issues/4889
值得注意的是:“隔离范围仅适用于模板,但不适用于指令未提供的标记。在1.2隔离范围之前有一个导致此类泄漏的错误。隔离点范围是它只适用于声明它的指令,而不适用于其他指令或标记。“(来自tbosch)
1.2.0 之前,同一DOM元素上的所有内容共享相同的范围。 因此1.2.0对使用隔离范围的指令的工作方式做了重大改变。
答案 1 :(得分:4)
设置scope: true
应解决问题。 http://jsfiddle.net/rug3J/1。我还建议遵循惯例并将其命名为scope
而不是$scope
,而不是依赖注入:
.directive('myDialog', function() {
return {
restrict: 'E',
scope: true,
link: function(scope) {
scope.test = function () {
scope.testMessage = 'Isolated Test loaded. Yes!';
}
}
};
答案 2 :(得分:0)
为了将正常标记与指令特定模板和功能结合起来,需要使用 transclude 选项,如下所示:
请参阅: jsFiddle
<强> HTML 强>
<div ng-app="myApp">
<div ng-controller="Ctrl">
<my-directive property="{{ something }}">
<p>{{ text }}</p>
</my-directive>
</div>
</div>
<强>的Javascript 强>
.controller('Ctrl', ['$scope', function($scope) {
$scope.text = 'This is a controllers text.';
$scope.something = 'This is another controllers text.';
}])
.directive('myDirective', function() {
return {
restrict: 'E',
transclude: true,
template: '<button ng-click="test()">Fire directives function</button><div ng-transclude></div><p>{{ property }}</p>',
scope: {
property: '@'
},
link: function(scope) {
scope.test = function () {
scope.property = 'Loaded directives text.';
}
}
};
});
现在这对我来说很好,但应该注意的是,不能覆盖范围的现有属性。