Javascript 1.0.x和1.2.x之间的AngularJS范围差异
在下一个稳定的AngularJS发布时,我正在将我的应用程序从版本1.0.8迁移到1.2 在AngularJS1.0.8中,可以为Javascript 1.0.x和1.2.x之间的AngularJS范围差异,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,在下一个稳定的AngularJS发布时,我正在将我的应用程序从版本1.0.8迁移到1.2 在AngularJS1.0.8中,可以为follow等指令设置一个单独的作用域。然后指令将使用自己的test()函数,而不是控制器的test()函数 HTML 在AngularJS1.2中,此行为不再有效。单击按钮立即启动控制器的test()函数 请参阅此JSFIDLE比较: 到底是什么发生了变化?我如何重现旧的行为 注 我发现我可以将指令模板放在一个额外的HTML文件中,或者将其编译为字符串以使其
follow
等指令设置一个单独的作用域。然后指令将使用自己的test()
函数,而不是控制器的test()
函数
HTML
在AngularJS1.2中,此行为不再有效。单击按钮立即启动控制器的test()
函数
请参阅此JSFIDLE比较:
如果没有其他属性可共享,则可以正常工作。我更新以传递一些任意属性。我现在应该如何继续?设置
范围:true
应该可以解决问题。我还建议遵循约定并将其命名为scope
,而不是$scope
,如果它不是依赖注入的:
.directive('myDialog', function() {
return {
restrict: 'E',
scope: true,
link: function(scope) {
scope.test = function () {
scope.testMessage = 'Isolated Test loaded. Yes!';
}
}
};
看起来这是突破性更改的预期结果:在1.2.0(在rc3之后)中拉入(参见1.2.0-$compile的第一个突破性更改): 修复了隔离作用域到处泄漏到同一元素上的其他指令的问题 隔离作用域现在仅对请求它的隔离指令及其模板可用。 非隔离指令不应在同一元素上获取隔离指令的隔离范围,而是接收原始范围(即新创建的隔离范围的父范围) 另请查看以下讨论: 值得注意的是:“隔离作用域仅应用于模板,而不应用于未由指令提供的标记。在1.2版本之前,隔离作用域存在导致此类泄漏的错误。隔离作用域的要点是,它仅适用于声明它的指令,而不适用于其他指令或标记。”(来自tbosch)
在1.2.0之前相同DOM元素上的所有内容都共享相同的作用域。因此1.2.0对具有隔离作用域的指令的工作方式进行了重大更改。为了将普通标记与特定于指令的模板和函数相结合,需要使用transclude选项,如因此: 请参阅: HTML
<div ng-app="myApp">
<div ng-controller="Ctrl">
<my-directive property="{{ something }}">
<p>{{ text }}</p>
</my-directive>
</div>
</div>
{{text}}
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.';
}
}
};
});
.controller('Ctrl',['$scope',函数($scope){
$scope.text='这是一个控制器文本';
$scope.something='这是另一个控制器文本';
}])
.directive('myDirective',function(){
返回{
限制:'E',
是的,
模板:“Fire directives function{{property}”,
范围:{
属性:'@'
},
链接:功能(范围){
scope.test=函数(){
scope.property='加载的指令文本';
}
}
};
});
现在这对我来说很好,但应该注意的是,不能覆盖作用域的现有属性。只要
作用域:true
。我还建议遵循约定,在不注入依赖项时将其命名为作用域
,而不是$scope
。@elclanrs哦,谢谢!这很简单。你能将其作为答案发布吗我可以将这些问题标记为已回答。有意思-我刚检查过,这在rc3和现在之间发生了变化。除了将范围设置为true之外,您还可以使用:范围:{test:'&}
。我确认了这是按预期工作的-通过测试进入隔离范围。@KayakDave感谢您提供的文档,这似乎是有意义的。{test:'&'}
对我来说不是选项,因为我不想使用controllers test()函数。为了确保一切都清楚,{test:'&'}将导致ng click=“test()”调用指令的test()
而不是控制器的。与将作用域设置为true的行为相同-除了您将对其他所有内容使用隔离作用域。您是否有一个理想的解释,为什么在我传递其他属性时它不工作?我相应地更新了我的问题和JSFIDLE。似乎只要您设置了隔离作用域,控制器的作用域就开始工作Dance.TBH我不确定Angular 1.0.8打破了以前的行为后发生了什么变化。如果你找到了解决方案,我很好奇,现在还没有在不太好的文档中找到任何相关内容……我可以确认,通过设置范围:忠实于我们的独立指令,我们解决了当前1.2.x迁移中的问题。嘿,太棒了回答,现在行为有意义了。
<div ng-app="myApp">
<div ng-controller="Ctrl">
<my-directive property="{{ something }}">
<p>{{ text }}</p>
</my-directive>
</div>
</div>
.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.';
}
}
};
});