简体   繁体   English

AngularJS Scope 1.0.x和1.2.x之间的差异

[英]AngularJS Scope differences between 1.0.x and 1.2.x

As of the release of the next stable AngularJS, I am migrating my application from version 1.0.8 to 1.2 . 在下一个稳定的AngularJS发布时,我正在将我的应用程序从1.0.8迁移到1.2

In AngularJS 1.0.8 it was possible to set up an isolated scope for directives like follow . 在AngularJS 1.0.8中 ,可以为诸如follow指令设置一个独立的范围。 The directive would then use its own test() function instead of the controller's test() function. 然后该指令将使用自己的test()函数而不是控制器的test()函数。

HTML HTML

<my-dialog property="something">
    <button ng-click="test()">Load Test</button>
    Check out the test: "{{ testMessage }}"
</my-dialog>

Javascript 使用Javascript

  .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!';
          }
      }
    };

In AngularJS 1.2 this behavior doesn't work anymore. 在AngularJS 1.2中,此行为不再起作用。 Clicking the button fires the controller's test() function now. 单击该按钮可立即触发控制器的test()函数。

See this jsFiddle comparison: 看到这个jsFiddle比较:

What exactly has changes and how can I reproduce the old behavior? 究竟有什么变化,我如何重现旧的行为?

Note 注意

I figured out I could place the directives template inside an extra HTML file or compile it as a string to get it working ( jsFiddle ) but it seems to be too much in my case, as the template is fixed and splitting the HTML over several partial HTML files is a hassle. 我发现我可以将指令模板放在一个额外的HTML文件中,或者将其编译成一个字符串以使其正常工作( jsFiddle )但在我的情况下似乎太多了,因为模板已修复并将HTML拆分为几个部分HTML文件很麻烦。

EDIT 编辑

@elclanr's answer works fine when there are no other properties to share. 当没有其他属性可供分享时, @ elclanr的答案正常。 I updated the jsFiddle to pass some arbitrary property. 我更新了jsFiddle以传递一些任意属性。 How should I proceed now? 我现在该怎么办?

It looks like this is an intended result of the breaking change: github.com/angular/angular.js/commit/… Which was pulled in 1.2.0 (after rc3) ( https://github.com/angular/angular.js/blob/master/CHANGELOG.md - see the first breaking change for 1.2.0 - $compile): 看起来这是破坏性变化的预期结果: github.com/angular/angular.js/commit / ...在1.2.0(在rc3之后)中提取( https://github.com/angular/angular。 js / blob / master / CHANGELOG.md - 看看1.2.0的第一个重大变化 - $ compile):

Fixes issue with isolate scope leaking all over the place into other directives on the same element. 修复了隔离范围泄漏到同一元素上的其他指令的问题。

Isolate scope is now available only to the isolate directive that requested it and its template. 隔离范围现在仅可用于请求它的isolate指令及其模板。

A non-isolate directive should not get the isolate scope of an isolate directive on the same element,instead they will receive the original scope (which is the parent scope of the newly created isolate scope). 非隔离指令不应该在同一元素上获取isolate伪指令的isolate范围,而是接收原始范围(它是新创建的隔离范围的父范围)。

Also check out this discussion: github.com/angular/angular.js/issues/4889 另请参阅此讨论: github.com/angular/angular.js/issues/4889

Notably: "The isolate scope is only applied to the template, but not to markup that was not contributed by the directive. Before 1.2 isolate scopes had a bug that caused this kind of leakage. The point of the isolate scope is that it only applies to the directive that declared it, and not to other directives or markup. " (from tbosch) 值得注意的是:“隔离范围仅适用于模板,但不适用于指令未提供的标记。在1.2隔离范围之前有一个导致此类泄漏的错误。 隔离范围的要点是它仅适用到声明它的指令,而不是其他指令或标记。 “(来自tbosch)

Previous to 1.2.0 everything on the same DOM element shared the same scope. 1.2.0之前,同一DOM元素上的所有内容共享相同的范围。 So 1.2.0 makes a substantial change to how directives with isolate scopes work. 因此,1.2.0对使用隔离范围的指令的工作方式进行了实质性的改变。

Setting scope: true should solve the issue. 设定scope: true应解决问题。 http://jsfiddle.net/rug3J/1 . http://jsfiddle.net/rug3J/1 I would also advise to follow convention and name it scope and not $scope when it's not dependency injected: 我还建议遵循约定并将其命名为scope而不是$scope ,而不是依赖注入:

.directive('myDialog', function() {
  return {
    restrict: 'E',
    scope: true,
    link: function(scope) {
      scope.test = function () {
        scope.testMessage = 'Isolated Test loaded. Yes!';
      }
    }
  };

In order to combine normal markup with directive specific templates and function one need to make use of the transclude option like so: 为了将正常标记与指令特定模板和函数结合起来,需要使用transclude选项,如下所示:

See: jsFiddle 见: jsFiddle

HTML HTML

<div ng-app="myApp">
    <div ng-controller="Ctrl">
        <my-directive property="{{ something }}">
            <p>{{ text }}</p>
        </my-directive>
    </div>
</div>

Javascript 使用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.';
            }
        }
    };
});

This works fine for me now but it should be noted that one can not override existing properties of the scope. 这对我来说现在很好用,但应该注意的是,不能覆盖范围的现有属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM