Angularjs ngClick不会在递归模板中触发

Angularjs ngClick不会在递归模板中触发,angularjs,angularjs-directive,angularjs-scope,angularjs-ng-click,Angularjs,Angularjs Directive,Angularjs Scope,Angularjs Ng Click,我开发了一个经典的递归菜单,它构建得很好。问题是ngClick从未从递归指令的元素中激发。 我知道这是一个范围问题,我尝试了许多配置,但没有运气 这是一把小提琴: 要调用的函数是retrieveFiles(path) 以及守则: app.directive("mediaTree", function ($compile) { return { restrict: "E", scope: { folder: '=', retrieveFiles: '=' }

我开发了一个经典的递归菜单,它构建得很好。问题是ngClick从未从递归指令的元素中激发。 我知道这是一个范围问题,我尝试了许多配置,但没有运气

这是一把小提琴:

要调用的函数是retrieveFiles(path)

以及守则:

app.directive("mediaTree", function ($compile) {
    return {
        restrict: "E",
        scope: { folder: '=', retrieveFiles: '=' },
        template:
            '<ul>' +
                '<li data-ng-repeat="child in folder.Children">' +
                    '<a href="#" data-ng-click="retrieveFiles(child.Path)">{{child.Name}}</a>' +
                    '<media-tree folder="child"></media-tree>' +
                '</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);
                });
            };
        }
    };
});


app.directive('mediaPanel', function ($compile) {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        link: function (scope, elem, attrs) {
            scope.retrieveFiles = function (me) {
                console.log("thanks for calling " + me);
            }
            scope.folder = {
                Name: 'Media',
                Path: '/',
                Children: [
                    {
                        Name: 'Child1',
                        Path: '/Child1',
                        Children: [
                            {
                                Name: 'GrandChild1',
                                Path: '/Child1/GrandChild1',
                                Children: []
                            }
                        ]
                    },
                    {
                        Name: 'Child2',
                        Path: '/Child2',
                        Children: [
                            {
                                Name: 'GrandChild2',
                                Path: '/Child1/GrandChild2',
                                Children: []
                            }
                        ]
                    }
                ]
            };

            elem.append($compile("<media-tree class='media-tree' folder='folder'></media-tree>")(scope));            
        }
    }
});
app.directive(“mediaTree”,函数($compile){
返回{
限制:“E”,
作用域:{文件夹:'=',检索文件:'='},
模板:
“
    ”+ “
  • ”+ '' + '' + “
  • ”+ “
”, 编译:函数(远程通讯,tAttr){ var contents=tElement.contents().remove(); var编译内容; 返回函数(范围、IELENT、iAttr){ 如果(!compiledContents){ compiledContents=$compile(目录); } compiledContents(范围,函数(克隆,范围){ 附加(克隆); }); }; } }; }); 应用程序指令('mediaPanel',函数($compile){ 返回{ 限制:'E', 替换:正确, 模板:“”, 链接:功能(范围、要素、属性){ scope.retrieveFiles=函数(me){ console.log(“感谢致电”+me); } scope.folder={ 名称:'媒体', 路径:“/”, 儿童:[ { 姓名:'Child1', 路径:'/Child1', 儿童:[ { 名称:'1', 路径:'/Child1/grand1', 儿童:[] } ] }, { 姓名:'Child2', 路径:'/Child2', 儿童:[ { 名称:'2', 路径:'/Child1/2', 儿童:[] } ] } ] }; 元素追加($compile(“”)(scope)); } } });
在这种情况下,我使用的方法是“requirecontrollerofparent指令”。在
mediaTree
指令中,添加:

require: "^mediaPanel"
现在所有的
mediaTree
节点都可以访问
mediaPanel
的控制器。编写一个,公开要调用的函数(注意:使用
this
,而不是
$scope
):

然后,
mediaTree
的链接功能可以访问此控制器及其
检索文件
成员:

compile: function (tElement, tAttr) {
    ...
    return function (scope, iElement, iAttr, mediaPanel) {
        // call mediaPanel.retrieveFiles(x) from here, or put it in scope
    };
}
我自由地重新整理了一下你的代码。有些编译并不是真的需要,我将数据定义移到了顶级控制器上,等等。请参阅fiddle with re arrangements and the working case:

compile: function (tElement, tAttr) {
    ...
    return function (scope, iElement, iAttr, mediaPanel) {
        // call mediaPanel.retrieveFiles(x) from here, or put it in scope
    };
}