使用AngularJs递归创建的指令中的控制器定义的功能



我正在尝试构建动态树组件,即像文件夹结构一样。我希望孩子们动态负载,因此与期望在初始化过程中存在整个结构的其他模块相反,我想在需要时加载元素。

因此,我将控制器函数绑定到指令。这是我的html:

<tree-model data="treedata" load-children="loadTree(n)" />

这定义了tree-model指令

app.directive( 'treeModel', function( $compile, $log, $http ) {
      return {
        restrict: 'E',
        scope: {
          node: '=data',
          loadChildren: '&'
        },
        link: function ( scope, element, attrs ) {
          var template =
            '<ul>' +
              '<li ng-model="node">' +
              '<span ng-switch="node.status">' +
                '<i ng-switch-when="collapsed" class="collapsed" ng-click="selectNodeHead(node)">C</i>' +
                '<i ng-switch-when="expanded" class="expanded" ng-click="selectNodeHead(node)">E</i>' +
                '<i ng-switch-default="" class="normal">N</i> ' +
              '</span>' +
              '<span ng-class="node.selected">{{node.label}}</span>' +
              '<span ng-repeat="c in node.children">' +
                '<tree-model data="c" load-children="loadChildren(n)" />' +
              '</span>' +
              '</li>' +
            '</ul>';
          var repl = function() {
            var newElement = angular.element(template);
            $compile(newElement)(scope);
            element.replaceWith(newElement);
          }
          scope.selectNodeHead = function(selectedNode) {
            if (selectedNode.children && selectedNode.children.length) {
              // Collapse
              selectedNode.children = undefined;
              selectedNode.hasChildren = true;
              selectedNode.status = "collapsed";
            } else {
              // Expand
              scope.loadChildren({n: selectedNode});
              selectedNode.status ="expanded";
              repl();
            }
          };
          repl();
        }
      };
    });

这是我的控制器:

app.controller('MyCtrl',
  function ($scope, $log, $http) {
    $scope.treedata = { "label": "Root", "status": "collapsed", "screen": "Root", "id": "999999", "hasChildren": true };
    $scope.loadTree = function(node) {
      $scope.output = "Node: " + node;
      node.children =[
        { "label": "Child 1", "status": "collapsed", "screen": "Child 1", "id": "999997", "hasChildren": true},
        { "label": "Child 2", "status": "normal", "screen": "Child 2", "id": "999995", "hasChildren": false}
      ];
    };
  });

所以我想递归建造树。对于第一个节点,我的控制器函数loadTree()可以将预期的node作为输入效果很好。但是,在调用loadTree()的孩子步骤中,但没有将node作为参数传递。

这似乎与孤立的范围有关。如果我做

scope.$parent.$parent.loadChildren({n: selectedNode});

而不是

scope.loadChildren({n: selectedNode});

在指令的扩展部分中,参数传递起作用。

这是一个证明问题的plunker:http://plnkr.co/edit/i4vducd7efmwez9izxmd

问题在于您在指令中如何调用模板内的方法。应该这样称呼:

'<tree-model data="c" load-children="loadChildren({n : n})" />'

您在这里的一个稍微修改的代码:http://jsfiddle.net/yyankowski/2zcpp/3/

最新更新