繁体   English   中英

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

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

在下一个稳定的AngularJS发布时,我正在将我的应用程序从1.0.8迁移到1.2

在AngularJS 1.0.8中 ,可以为诸如follow指令设置一个独立的范围。 然后该指令将使用自己的test()函数而不是控制器的test()函数。

HTML

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

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

在AngularJS 1.2中,此行为不再起作用。 单击该按钮可立即触发控制器的test()函数。

看到这个jsFiddle比较:

究竟有什么变化,我如何重现旧的行为?

注意

我发现我可以将指令模板放在一个额外的HTML文件中,或者将其编译成一个字符串以使其正常工作( jsFiddle )但在我的情况下似乎太多了,因为模板已修复并将HTML拆分为几个部分HTML文件很麻烦。

编辑

当没有其他属性可供分享时, @ elclanr的答案正常。 我更新了jsFiddle以传递一些任意属性。 我现在该怎么办?

看起来这是破坏性变化的预期结果: github.com/angular/angular.js/commit / ...在1.2.0(在rc3之后)中提取( https://github.com/angular/angular。 js / blob / master / CHANGELOG.md - 看看1.2.0的第一个重大变化 - $ compile):

修复了隔离范围泄漏到同一元素上的其他指令的问题。

隔离范围现在仅可用于请求它的isolate指令及其模板。

非隔离指令不应该在同一元素上获取isolate伪指令的isolate范围,而是接收原始范围(它是新创建的隔离范围的父范围)。

另请参阅此讨论: github.com/angular/angular.js/issues/4889

值得注意的是:“隔离范围仅适用于模板,但不适用于指令未提供的标记。在1.2隔离范围之前有一个导致此类泄漏的错误。 隔离范围的要点是它仅适用到声明它的指令,而不是其他指令或标记。 “(来自tbosch)

1.2.0之前,同一DOM元素上的所有内容共享相同的范围。 因此,1.2.0对使用隔离范围的指令的工作方式进行了实质性的改变。

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

为了将正常标记与指令特定模板和函数结合起来,需要使用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.';
            }
        }
    };
});

这对我来说现在很好用,但应该注意的是,不能覆盖范围的现有属性。

暂无
暂无

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

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