Angularjs 指令';s的独立作用域变量是未定义的,如果它包装在一个指令中,该指令在其模板中启用了ng if和tranclusion

Angularjs 指令';s的独立作用域变量是未定义的,如果它包装在一个指令中,该指令在其模板中启用了ng if和tranclusion,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,我面临的问题如下例所示: 你好,{{name}}! var myApp=angular.module('myApp',[]); myApp.controller('DemoCtrl',['$scope',函数($scope){ $scope.name='nadia'; $scope.nameForNestedDirective='eirini'; }]) .directive('myWrapperDirective',function(){ 返回{ 限制:“A”, 作用域:{}, 是的, 模

我面临的问题如下例所示:


你好,{{name}}!
var myApp=angular.module('myApp',[]);
myApp.controller('DemoCtrl',['$scope',函数($scope){
$scope.name='nadia';
$scope.nameForNestedDirective='eirini';
}])
.directive('myWrapperDirective',function(){
返回{
限制:“A”,
作用域:{},
是的,
模板:“你好,”,
链接:功能(范围、元素){
scope.isEnabled=true;
}
}
})
.directive('myNestedDirective',function(){
返回{
限制:“A”,
范围:{
嵌套数据:'='
},
模板:“{nestedData}}”,
};
});
我想创建一个指令(myWrapperDirective),它将封装许多其他指令,例如我的示例中的“myNestedDirective”。
“myWrapperDirective”应根据ng if表达式的值决定是否显示其内容,但如果内容是类似于“myNestedDirective”的指令,且具有独立作用域,则未定义“myNestedDirective”的作用域变量“nestedData”。

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

用图表说明:

外部作用域-DemoCtrl
-定义:名称
-定义:nameForNestedDirective
+用途:名称
内部隔离作用域1-MyWrapper指令
-定义:(无)
-继承:(什么都没有!-它是孤立的)
+用法:(无)
*将nestedData=nameForNestedDirective传递给nested指令,但
此处未定义nameForNestedDirective!
内部隔离作用域2-myNestedDirective
-定义:嵌套数据(来自范围定义)
-继承:(什么都没有!-它是孤立的)
+使用嵌套数据
您可以通过注释包装器指令的范围定义来说服自己这是事实(“hello eirini”按预期显示):

我不确定包装器指令是否真的需要有一个独立的作用域。如果没有,也许移除隔离作用域将解决您的问题。否则,您必须:

  • 首先将数据传递给包装器,然后传递给嵌套指令
  • 将数据传递给wrapper指令,为其编写一个公开数据的控制器,然后
    require
    nested指令中的wrapper控制器

  • 不幸的是,需要包装器指令的隔离作用域,因为我想保留'isEnabled'变量的值,它可能会因包装器指令在同一控制器内的每次出现而变化,因此如果我们没有隔离作用域,对于wrapper指令的所有出现,“isEnabled”值可以相同。对于隔离作用域情况,您可以从顶级控制器“捆绑”JS对象中内部指令所需的所有数据,并将该对象传递给wrapper。在这种情况下,您可以使用scope:true,它将为指令的每个实例提供其自己的父(DemoCtrl)作用域克隆。请记住,它是一个克隆,因此父范围中的更改不会影响内容。如果您需要它是可绑定的,那么您应该将它作为一个属性传递到包装器上(并将该属性包含在隔离范围中)。
    <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>',
    
        };
    
    });
    
    .directive('myWrapperDirective', function(){
        return {
            ...
            //scope: {},
            ...