如果指令的隔离范围变量包含在启用了模板ng-if和tranclusion的指令中,则它是未定义的

时间:2014-03-10 09:15:06

标签: angularjs angularjs-directive angularjs-scope

我面临的是一个问题,在以下示例中进行了演示:

http://jsfiddle.net/nanmark/xM92P/

<div ng-controller="DemoCtrl">
  Hello, {{name}}!
    <div my-wrapper-directive>
        <div my-nested-directive nested-data="nameForNestedDirective"></div>

    </div>
</div>

var myApp = angular.module('myApp', []);
myApp.controller('DemoCtrl',['$scope', function($scope){
    $scope.name = 'nadia';
    $scope.nameForNestedDirective = 'eirini';
}])
.directive('myWrapperDirective', function(){
    return {
        restrict: 'A',
        scope: {},
        transclude: true,
        template: "<div ng-if='isEnabled'>Hello, <div ng-transclude></div></div>",
        link: function(scope, element){
            scope.isEnabled = true;
        }
    }
})
.directive('myNestedDirective', function(){
    return {
        restrict: 'A',
        scope: {
            nestedData: '='
        },
        template: '<div>{{nestedData}}</div>',

    };

});

我想创建一个指令(myWrapperDirective),它将包含许多其他指令,例如'myNestedDirective of my example。 'myWrapperDirective'应根据ng-if表达式的值决定是否显示其内容,但如果内容是带有隔离范围的'myNestedDirective'之类的指令,则'myNestedDirective'的范围变量'nestedData'未定义。

1 个答案:

答案 0 :(得分:1)

问题在于双嵌套隔离范围。您看,您正在使用nameForNestedDirective变量,该变量在内部作用域的外部作用域中定义。这意味着继承此变量,因此将undefined传递给嵌套指令。

解释图表:

Outer scope - DemoCtrl
    - Defines: name
    - Defines: nameForNestedDirective
    + Uses: name

    Inner isolated scope 1 - myWrapperDirective
        - Defines: (nothing)
        - Inherits: (NOTHING! - It is isolated)
        + Uses: (nothing)
        * Passes nestedData=nameForNestedDirective to nested directive, but
          nameForNestedDirective is undefined here!

        Inner isolated scope 2 - myNestedDirective
            - Defines: nestedData (from scope definition)
            - Inherits: (NOTHING! - It is isolated)
            + Uses nestedData

你可以通过注释掉包装器指令的范围定义来说服自己就是这种情况(“hello eirini”按预期显示):

.directive('myWrapperDirective', function(){
    return {
        ...
        //scope: {},
        ...

我不确定包装器指令是否确实需要具有隔离范围。如果没有,可能删除隔离范围将解决您的问题。否则你将要么:

  1. 首先将数据传递给包装器,然后传递给嵌套指令
  2. 将数据传递给包装器指令,为其公开数据的控制器,然后从嵌套指令中require包装器控制器。