递归自定义树视图 angularjs 指令调用 ng-click 两次

Recursive Custom Tree view angularjs Directive calls ng-click twice

我想用 Angularjs recursivelyTreeView Directive ..这是代码:

Index.html

<div ng-controller='TestController' ng-model='trees'>
        <tree model="trees" is-expanded="false"></tree>
</div>

树和节点指令

    function treeDirectiveFactory() {

        return {
            restrict: 'E',
            scope: {
                model: '=model'
            },
            //require: 'node', 
            templateUrl: '/_Core/DirectiveCore/Tree/TreeTemplate.html',
            controller: 'TreeController',
            controllerAs: 'c'

        }
    };
function nodeDirectiveFactory($compile) {

    return {
        restrict: 'E',           
        scope: {
            model: '=model'
        },
        templateUrl: '/_Core/DirectiveCore/Tree/NodeTemplate.html',
        controller: 'NodeController',
        controllerAs: 'c',       
        link: function(scope, element, attr, treeCtrl) {

                if (scope.model.nodes.length > 0) {
                    element.append('<ul><node ng-repeat=" node in c.model.nodes" model="node"></node></ul>');
                    $compile(element.contents())(scope);
                }
            }

    }
};


树和节点模板

<div ng-repeat='tree in c.model'>
   <node model='tree'></node>
 </div>

<li style="list-style-type: none;" >
    <a href="{{c.model.link}}" ng-click='c.nodeSelect()' ng-show={{c.model.isVisible}}>
        <span ng-class='c.model.cssClass'></span>
        {{c.model.text}}
    </a>  
</li>

树和节点控制器

        module Core.Controllers {

        export class TreeController extends Core.Controllers.BaseCtl {

            constructor($scope: ng.IScope) {
                super($scope);

                this.init();
            }

            model: any;

            getModel(): any {
                return <any>this.scope["model"];
            }

            init() {
                this.model = this.getModel();
            }
        }

    } 
module Core.Controllers {

    export class NodeController extends Core.Controllers.BaseCtl {

        constructor($scope: ng.IScope) {
            super($scope);

            this.init();
        }

        t: number;
        model: any;
        isVisible: boolean;
        getModel(): any {
            return <any>this.scope["model"];
        }

        init() {
            this.t = 0;
            this.model = this.getModel();
        }

        nodeSelect() {

            if (this.model.nodes.length > 0) {

                if (this.model.cssClass === 'glyphicon glyphicon-plus')
                    this.model.cssClass = 'glyphicon glyphicon-minus';
                else
                    this.model.cssClass = 'glyphicon glyphicon-plus';

                angular.forEach(this.model.nodes, function(node) {
                    node.isVisible = !node.isVisible;
                });
            }

        }
    }

}

nodeSelect函数中改变样式的算法是暂时的,它会变得更好它只是为了测试。问题是因为 link 函数和 recursive 在每个 ng-click 中调用 nodeSelect 触发器两次,另一方面,如果我将 link 更改为 compileprelink 子节点不会出现。我知道 link 函数中的算法必须处于 compile 阶段,但我不知道该怎么做。 我想要一棵可以选择 css 图标的树。

这里是示例树对象。

    var trees = [
                {
                    text: 'A',
                    link: '#',
                    cssClass: 'glyphicon glyphicon-plus',
                    isVisible: true,
                        nodes: [
                            {
                                text: 'A1',
                                link: '#',
                                cssClass: 'glyphicon glyphicon-file',
                                isVisible: true,
                                nodes:[]
                            }
];

为了防止 ng-click 触发两次..我们应该使用 event.stopPropagation(),感谢 nhd for this answer.