AngularJS指令隔离作用域和父作用域

AngularJS指令隔离作用域和父作用域,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,我正在尝试实现一个递归指令,似乎要让它很好地工作,我需要定义一个隔离的作用域以及对父作用域的访问。基本上,我希望我的指令能够访问作为指令本身属性设置的变量,但我也希望能够访问控制器范围内设置的变量和方法。有没有办法把两者结合起来?我试过使用transclude,但我想我不能完全确定我是否正确使用了它。下面是我的问题的一个小例子,我希望指令中的每个“child”都能够调用函数sayHi():您必须将sayHi函数传递给您的指令。 指令创建它们自己的作用域,所以sayHi函数不是指令作用域的一部分,

我正在尝试实现一个递归指令,似乎要让它很好地工作,我需要定义一个隔离的作用域以及对父作用域的访问。基本上,我希望我的指令能够访问作为指令本身属性设置的变量,但我也希望能够访问控制器范围内设置的变量和方法。有没有办法把两者结合起来?我试过使用transclude,但我想我不能完全确定我是否正确使用了它。下面是我的问题的一个小例子,我希望指令中的每个“child”都能够调用函数
sayHi()

您必须将sayHi函数传递给您的指令。 指令创建它们自己的作用域,所以sayHi函数不是指令作用域的一部分,允许它的方法是创建一个新的道具并传递它

HTML


JS

var module=angular.module('myapp',[]);
模块控制器(“TreeCtrl”,功能($scope){
$scope.treeFamily={
姓名:“家长”,
儿童:[{
姓名:“Child1”,
儿童:[{
名称:“1”,
儿童:[]
},{
姓名:"孙女2",,
儿童:[]
}]
}, {
姓名:“Child2”,
儿童:[]
}]
};
$scope.sayHi=函数(名称){
警报(名称+'说你好!')
}
});
指令(“树”,函数($compile){
返回{
限制:“E”,
范围:{
族:“=”,
早希:“&”
},
是的,
模板:
“{{family.name}

”+ “
    ”+ “
  • ”+ '' + “打招呼”+ “
  • ”+ “
”, 编译:函数(远程通讯,tAttr){ var contents=tElement.contents().remove(); var编译内容; 返回函数(范围、IELENT、iAttr){ 如果(!compiledContents){ compiledContents=$compile(目录); } compiledContents(范围,函数(克隆,范围){ 附加(克隆); }); }; } }; });
如果使用组件(需要v1.5+)而不是指令,这会容易得多。组件允许绑定函数,但当组件是递归的时,它会中断。不过,活动是有效的:谢谢,这个解决方案是有效的。这也让我意识到指令可能不是解决我问题的方法。实际上,我的子元素需要从父作用域访问许多变量和方法,并像这样传递它们中的每一个,这加重了我的指令。最后,我使用了这里描述的基于模板的解决方案
<div ng-app="myapp">
    <div ng-controller="TreeCtrl">
        <tree family="treeFamily"
          say-hi="sayHi(name)"
         ngTransclude></tree>
    </div>
</div>
var module = angular.module('myapp', []);

module.controller("TreeCtrl", function($scope) {
    $scope.treeFamily = {
        name : "Parent",
        children: [{
            name : "Child1",
            children: [{
                name : "Grandchild1",
                children: []
            },{
                name : "Grandchild2",
                children: []
            }]
        }, {
            name: "Child2",
            children: []
        }]
    };
    $scope.sayHi = function(name){
        alert(name+' says hello!')
    }
});

module.directive("tree", function($compile) {
    return {
        restrict: "E",
        scope: {
            family: '=',
          sayHi : '&'
         },
        transclude: true,
        template: 
            '<p>{{ family.name }}</p>'+
            '<ul>' + 
                '<li ng-repeat="child in family.children">' + 
                    '<tree family="child" say-hi="sayHi(name)"></tree>' +
                    '<button ng-click="sayHi({name : child.name})">Say Hi</button>' +
                '</li>' +
            '</ul>',
        compile: function(tElement, tAttr) {
            var contents = tElement.contents().remove();
            var compiledContents;
            return function(scope, iElement, iAttr) {
                if(!compiledContents) {
                    compiledContents = $compile(contents);
                }
                compiledContents(scope, function(clone, scope) {
                         iElement.append(clone); 
                });
            };
        }
    };
});