12

随着下一个稳定的 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以传递一些任意属性。我现在应该如何进行?

4

3 回答 3

5

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

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

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

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

另请查看此讨论:github.com/angular/angular.js/issues/4889

值得注意的是:“隔离范围仅适用于模板,而不适用于不是由指令贡献的标记。在 1.2 之前,隔离范围有一个错误导致这种泄漏。隔离范围的要点是它只适用于声明它的指令,而不是其他指令或标记。 ”(来自 tbosch)

在1.2.0之前,同一个 DOM 元素上的所有内容都共享相同的范围。 因此 1.2.0 对具有隔离作用域的指令的工作方式进行了重大更改。

于 2013-11-13T04:25:08.163 回答
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!';
      }
    }
  };
于 2013-11-13T02:22:09.030 回答
0

In order to combine normal markup with directive specific templates and function one need to make use of the transclude option like so:

See: 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.';
            }
        }
    };
});

This works fine for me now but it should be noted that one can not override existing properties of the scope.

于 2013-11-14T00:15:18.733 回答