0

我一直在努力尝试所有可以想象的组合,以在对树结构进行更改时尝试让树菜单的分支正确刷新。基本上我所拥有的是一组递归嵌套指令来显示树的分支。我构建了一个 javascript 类来存储树结构的任何给定部分的指令数据。该类包含一个模型,我基本上已经接口,因此它有一些已知的方法(例如 getVals() 从 ajax 加载数据和 getId()、getName()、getLabel() 来检索用于构建树的公共属性) . 然后我以两种方式使用它来构建具有该对象对的树,第一种是对于给定的分支点,它将包含一个描述“组”的模型(具有多个子分支)(从基本上是一组学说实体样式对象的 Doctrine ORM 集合加载数据),另一个是表示作为实际分支的实体的单个模型。这个想法是任何主干(分支点)都将有两个选项 - 一个显示该组/父级的详细信息,另一个仅显示子级的名称。然后每个孩子都可以选择显示它的详细信息或显示它的孩子等等。

function treeBranch() {
    this.refresh = false;

    // class and title information for expander button
    this.toggleShown = function() {
        this.vis = !(this.vis);

        if(this.vis == true) {
            this.trunkClass = 'glyphicon glyphicon-chevron-down';
            this.trunkTitle = 'collapse';
        } else {
            this.trunkClass = 'glyphicon glyphicon-chevron-right';
            this.trunkTitle = 'expand';
        }
};

    // default populator code
    this.populate = function(toggle,force,pcbf) {
        toggle = (typeof(toggle) == 'boolean') ? toggle : true;
        force  = (typeof(force) == 'force') ? force : false;
        var br = this;
        if((typeof(br.subBranches) == 'undefined') || (br.subBranches.length == 0))
            force = true;

        if((typeof(br.model) != 'undefined') && (typeof(br.loadMethod) != 'undefined')) {
            br.model[br.loadMethod](
                function() {
                    br.subBranches = []; // reset subBranches array
                    for(var k in br.model.subs) { // subs should be loaded with a keyed array
                        var newSubBranch = new treeBranch();
                        newSubBranch.model = br.model.subs[k];
                        newSubBranch.label = 'Name: ' + newSubBranch.model.getName(); // expects model to have a getName method
                        newSubBranch.trunk = br;
                       br.subBranches.push(newSubBranch);
                    }
                    (toggle == true) && br.toggleShown();
                     (typeof(pcbf) == 'function') && pcbf();
                 },
                 force,
                 br.model.getFilter()
             );
         }
     };

     this.getLabel = function() {
         if(this.model != null) {
             return ((typeof(this.model.getId) == 'function') ? this.model.getId() : '') +
                 ((typeof(this.model.getName) == 'function') ? ' '+this.model.getName() : '');
         } else {
             return this.label;
         }
     }

     // core properties
     this.label = '';
     this.vis = false;
     this.trunkClass = 'glyphicon glyphicon-chevron-right';
     this.trunkTitle = 'expand';
     this.subBranches = [];
     this.trunk = null;

     this.model = null;
     this.loadMethod = 'getVals'; // function of model to populate it with data

 };
/**
   -Trunk {treeBranch with entity as model}
      [show details option]
      +--> branches {treeBranch instance with collection as model}
           [show branches/children option]
           - branch1 {treeBranch entity model}
            [show details option]
                +--> branches {treeBranch collection model}
                     [show branches/children option]
                     - subbranch1 ... etc
           - branch2 {treeBranch with entity as model}
            [show details option]
                +--> branches {treeBranch collection model}
                     [show branches/children option]
     ... etc ...
*/

当我开始添加函数来操作给定分支点(实体)的属性和/或添加/删除/移动分支本身时,我的问题就出现了。我有用于添加/更新/删除的表单(仍在移动中),但是当保存数据时,因为我的模型正在执行自己的 ajax 休息调用,树不会更新以反映更改。问题之一是我在孩子的 UL 标记之后设置了添加按钮 - 我可以很好地更新它,因为它与具有 UL 标记的模板位于同一指令中。但是孩子们处于第二个指令之下,该指令与 LI 周围的 ng-repeat 相关联,用于显示每个子分支包装器。因此更新/删除按钮显示在该模板中,但我需要刷新的范围是父级。我知道我可以做 $parent.$parent。reload() 来调用我的刷新脚本,但是当我开始执行“移动”功能时,我可能正在将列表项移动到树的一半。我在模板的分支点有一个“刷新”按钮,并尝试执行 document.getElementById('branchpointX').click(); 但这很笨拙,我一直在尝试找出在该范围的 .reload() 函数内刷新范围内该点的最佳方法。$scope.$apply 有时会与现有的 $digest 刷新发生冲突,即使将它们放入 $timeout 有时仍会引发刷新已在进行中的错误。并尝试做一个 document.getElementById('branchpointX').click(); 但这很笨拙,我一直在尝试找出在该范围的 .reload() 函数内刷新范围内该点的最佳方法。$scope.$apply 有时会与现有的 $digest 刷新发生冲突,即使将它们放入 $timeout 有时仍会引发刷新已在进行中的错误。并尝试做一个 document.getElementById('branchpointX').click(); 但这很笨拙,我一直在尝试找出在该范围的 .reload() 函数内刷新范围内该点的最佳方法。$scope.$apply 有时会与现有的 $digest 刷新发生冲突,即使将它们放入 $timeout 有时仍会引发刷新已在进行中的错误。

所以我想知道在所述指令的层次结构树中刷新特定指令的最佳方法是什么?我已经尝试在每个 subBranch 中构建一个堆栈,其分支点的标签返回到原点,但是如果我尝试运行 treeStack['someParentId'].reload() 它在子范围内似乎不起作用.

西南

4

2 回答 2

0

文字太多。

所以,这是简单的树指令

JSON:

var youList = [
            {'display': 'parent 1', 'description': 'parent 1 desc', 'children': [
                {'display': 'parent 1 child 1', 'description': 'parent 1 desc child 1', 'children': [
                    {'display': 'parent 1 child 1 sub-child 1', 'description': 'parent 1 desc child 1 sub-child 1', 'children': []},
                    {'display': 'parent 1 child 1 sub-child 2', 'description': 'parent 1 desc child 1 sub-child 2', 'children': []}
                ]},
                {'display': 'parent 1 child 2', 'description': 'parent 1 desc child 2', 'children': []}
            ]},
            {'display': 'parent 2', 'description': 'parent 2 desc', 'children': [
                {'display': 'parent 2 child 1', 'description': 'parent 2 desc child 1', 'children': []},
                {'display': 'parent 2 child 2', 'description': 'parent 2 desc child 2', 'children': []}
            ]}
        ];

HTML:

<my-tree parent-list="youList"></my-tree>

指示:

.directive('myTree', function ($compile) {
    return {
        restrict: 'E',
        link: function (scope, element, attrs) {
            var parentList = attrs.parentList;
            var template =
                '<ul>' +
                '   <li class="" ng-repeat="item in ' + parentList + '">' +
                '      <label>{{item.display}}</label> : <small>{{item.description}}</small>' +
                '      <my-tree parent-list="item.children" ng-if="item.children && item.children.length > 0"></my-tree>' +
                '   </li>' +
                '</ul>';

            element.html('').append($compile(template)(scope));
        }
    }
})

添加必要的按钮添加/删除以使用“yourList”变量进行操作。通过更新 'yourList' 的任何部分,您的树结构会得到更新。

应该很容易。不需要技能:)

于 2015-06-17T15:53:44.983 回答
0

原来我一直在寻找的是使用 rootScope 设置 $broadcast 触发器,然后我可以在每个相应的范围内使用 $on 和回调函数进行监听。

例如,保存时,调用时具有回调函数,因此我的编辑指令(在不同的工厂控制器中)可以添加 $rootScope.$broadcast('branch1Reload'); 到回调,然后该分支的指令只需要一个 $rootscope.$on('branch1Reload', function() { /* do stuff */ ; scope.reload(); });

于 2015-06-17T20:52:29.977 回答