【问题标题】:Why I can't access the right scope?为什么我无法访问正确的范围?
【发布时间】:2014-01-27 15:28:11
【问题描述】:

html:

<!doctype html>
<html>
<head>
</head>
<body>
<div ng-app="project">
   <div ng-controller="mainCtrl">
    {{ property1 }}
    <br />
    {{ property2 }}
    <div class="ts" d-child property1="{{ property1 }}cloud" property2="property2">
        property1: {{ property1 }}
        <br />
        property2: {{ property2 }}
    </div>

    </div>
    </div>
    </body>
</html>

js:

angular.module('project', [])
.controller('mainCtrl', function($scope) {
    $scope.property1 = 'ss';
    $scope.property2 = 'dd';
});

angular.module('project')
.directive('dChild', function() {
    return {
        restrict: 'A',
        scope: {
            property1: '@',
            property2: '='
        },
        link: function(scope, element, attrs) {

        }
//      template: '<input type="text" ng-model="property1" />'
    }
})

我以为property1: {{ property1 }}会是“property1:sscloud”,结果却是“ss”,好像还是指mainCtrl控制器的作用域,不应该是指作用域吗d-child 指令?

如果我在指令中使用模板,它确实引用了正确的范围并显示“sscloud”,谁能告诉我为什么?

【问题讨论】:

  • nuage,你能接受我的回答吗

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

当 Angular 编译具有独立作用域的元素时,它有一些规则:

  • 如果指令没有模板属性(或 templateUrl),则内部内容将附加到父范围。实际上在this commit 之前,内部内容正在获得隔离范围。检查您的示例以确认它适用于低于 1.2 的版本
  • 如果指令确实有模板属性,那么它将覆盖内部内容(除非被转入)。
  • 仅当您使用嵌入时,内部内容才会附加到同级范围(非隔离)。
  • Angular 以这种方式工作的原因是让可重用组件松散耦合,并且不会对您的应用程序产生任何副作用。
  • 没有隔离范围的指令不会从同一元素上的隔离指令中获得隔离范围 (see important commit)。
  • 指令的模板无论如何都会获得隔离范围。

如果你想改变这种行为,你可以像这样将隔离作用域传递给转换函数:

angular.module('project')
.directive('dChild', function() {
    return {
        restrict: 'A',
        transclude: true,        
        scope: {
            property1: '@',
            property2: '='
        },
        link: function(scope, element, attrs, ctrl, linker) {
          linker(scope, function(clone, scope){
            element.append(clone)
          })
        }
    }
})

我强烈建议您查看这些教程:

阅读更多:

【讨论】:

  • 我真的需要在嵌入函数中挖掘更多,这是能够在被嵌入的 html 中使用隔离范围的好方法。
  • 我不建议在指令和嵌入内容之间共享相同的隔离范围,因为它将视图与指令耦合,这是一种不好的做法。这仅对学习和 hacky 解决方案有用。
  • 确实,1.2.x 中为避免范围泄漏所做的修复很好。我只是在学习它背后的“魔力”,这个答案是一个起点。
  • 我不能,我没有写这个问题:)
  • @JesusRodriguez 哦,我的错
【解决方案2】:

我认为你必须使用transclude option。 事实上,正如AngularJS docs 所说:

What does this transclude option do, exactly? transclude makes the contents of 
a directive with this option have access to the scope outside of the directive 
rather than inside.

因为您创建的Directives 孤立 scope

更多文档在:

http://docs.angularjs.org/guide/directive

【讨论】:

    【解决方案3】:

    我不太确定这一点,我很确定这与每个 {{}} 何时被评估以及指令的范围何时变得孤立有关。我的建议是将内容放在模板中,因为这样做似乎可以正常工作。

    如果您想详细了解指令作用域中“@”和“=”的区别,这里是我找到的关于它的最佳文本。

    What is the difference between '@' and '=' in directive scope in AngularJS?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 2013-11-03
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多