为什么我无法访问正确的范围?

时间:2014-01-09 07:31:21

标签: angularjs angularjs-directive angularjs-scope

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',任何人都可以告诉我为什么?

3 个答案:

答案 0 :(得分:5)

当angular编译具有隔离范围的元素时,它有一些规则:

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

如果要更改此行为,可以将隔离范围传递给tranclusion函数,如下所示:

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)
          })
        }
    }
})

我强烈建议您阅读这些教程:

并阅读更多内容:

答案 1 :(得分:0)

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

如果你想在指令范围内阅读更多关于“@”和“=”的区别,这里是我发现的最好的文字。

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

答案 2 :(得分:0)

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

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