刷新 angularjs 中的特定指令
refresh specific directives in angularjs
我一直在竭尽全力尝试所有可以想象的组合,以尝试在对树结构进行更改时使树菜单的分支正确刷新。本质上,我拥有的是一组递归嵌套指令,用于显示树的分支。我构建了一个 javascript class 来存储树结构的任何给定部分的指令数据。
class 包含一个我基本上已经连接的模型,因此它有一些已知的方法(例如 getVals() 从 ajax 和 getId()、getName()、getLabel() 加载数据到检索用于构建树的公共属性)。然后,我以两种方式使用它来构建具有 object 对的树,第一种是对于给定的分支点,它将包含一个模型(具有多个子分支)描述 'group'(具有数据从 Doctrine ORM 集合加载,该集合基本上是一个 Doctrine 实体样式的数组 objects),另一个是表示作为实际分支的实体的单个模型。
这个想法是任何主干(分支点)将有两个选项 - 一个显示 group/parent 的详细信息,另一个仅显示 children 的名称。然后每个 child 将有一个选项来显示它的详细信息或显示它的 children 等等。
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 ...
*/
当我开始添加函数来操纵给定分支点(实体)and/or add/delete/move 分支本身的属性时,我的问题就来了。我有适用于 add/update/delete 的表格(仍在移动中)但是当保存数据时,因为我的模型正在执行他们自己的 ajax 休息调用,树不会更新以反映变化。
问题之一是我在 children 的 UL 标签之后设置了添加按钮——我可以很好地更新它,因为它与带有 UL 标签的模板位于同一指令中。但是 children 在第二个指令下,该指令与 LI 周围的 ng-repeat 相关联,用于显示每个 sub-branch 包装器。因此 update/delete 按钮显示在该模板中,但我需要刷新的范围是 parent。
我知道我可以执行 $parent.$parent.reload() 来调用我的刷新脚本,但是当我开始执行 'move' 功能时,我可能会移动列表项 half-way穿过树。
我在模板的分支点有一个 'refresh' 按钮,并尝试执行 document.getElementById('branchpointX').click();但这很笨拙,我一直在尝试找出在该范围的 .reload() 函数内刷新范围内该点的最佳方法。 $scope.$apply 有时会与现有的 $digest 刷新发生冲突,甚至将它们放入 $timeout 中有时仍会抛出一个错误,表明刷新已经在进行中。
所以我想知道在所述指令的层次结构树中刷新特定指令的最佳方法是什么?我已经尝试在每个子分支中构建一个堆栈,并将其 branch-points 的标签返回到原点,但是如果我尝试 运行 treeStack['someParentId'].reload() 它不会似乎在 child 范围内工作。
西南
文字过多。
所以,这是一个简单的树指令
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));
}
}
})
添加必要的按钮 add/delete 以使用 'yourList' 变量进行操作。
通过更新 'yourList' 的任何部分,您的树结构得到更新。
应该很容易。无需技能:)
原来我正在寻找的是使用 rootScope 设置 $broadcast 触发器,然后我可以使用 $on 和每个相应范围中的回调函数进行监听。
例如调用保存时有一个回调函数,所以我的编辑指令(在不同的工厂控制器中)可以添加 $rootScope.$broadcast('branch1Reload');到回调,那么该分支的指令只需要一个 $rootscope.$on('branch1Reload', function() { /* do stuff */ ; scope.reload(); });
我一直在竭尽全力尝试所有可以想象的组合,以尝试在对树结构进行更改时使树菜单的分支正确刷新。本质上,我拥有的是一组递归嵌套指令,用于显示树的分支。我构建了一个 javascript class 来存储树结构的任何给定部分的指令数据。 class 包含一个我基本上已经连接的模型,因此它有一些已知的方法(例如 getVals() 从 ajax 和 getId()、getName()、getLabel() 加载数据到检索用于构建树的公共属性)。然后,我以两种方式使用它来构建具有 object 对的树,第一种是对于给定的分支点,它将包含一个模型(具有多个子分支)描述 'group'(具有数据从 Doctrine ORM 集合加载,该集合基本上是一个 Doctrine 实体样式的数组 objects),另一个是表示作为实际分支的实体的单个模型。 这个想法是任何主干(分支点)将有两个选项 - 一个显示 group/parent 的详细信息,另一个仅显示 children 的名称。然后每个 child 将有一个选项来显示它的详细信息或显示它的 children 等等。
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 ...
*/
当我开始添加函数来操纵给定分支点(实体)and/or add/delete/move 分支本身的属性时,我的问题就来了。我有适用于 add/update/delete 的表格(仍在移动中)但是当保存数据时,因为我的模型正在执行他们自己的 ajax 休息调用,树不会更新以反映变化。 问题之一是我在 children 的 UL 标签之后设置了添加按钮——我可以很好地更新它,因为它与带有 UL 标签的模板位于同一指令中。但是 children 在第二个指令下,该指令与 LI 周围的 ng-repeat 相关联,用于显示每个 sub-branch 包装器。因此 update/delete 按钮显示在该模板中,但我需要刷新的范围是 parent。 我知道我可以执行 $parent.$parent.reload() 来调用我的刷新脚本,但是当我开始执行 'move' 功能时,我可能会移动列表项 half-way穿过树。 我在模板的分支点有一个 'refresh' 按钮,并尝试执行 document.getElementById('branchpointX').click();但这很笨拙,我一直在尝试找出在该范围的 .reload() 函数内刷新范围内该点的最佳方法。 $scope.$apply 有时会与现有的 $digest 刷新发生冲突,甚至将它们放入 $timeout 中有时仍会抛出一个错误,表明刷新已经在进行中。
所以我想知道在所述指令的层次结构树中刷新特定指令的最佳方法是什么?我已经尝试在每个子分支中构建一个堆栈,并将其 branch-points 的标签返回到原点,但是如果我尝试 运行 treeStack['someParentId'].reload() 它不会似乎在 child 范围内工作。
西南
文字过多。
所以,这是一个简单的树指令
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));
}
}
})
添加必要的按钮 add/delete 以使用 'yourList' 变量进行操作。 通过更新 'yourList' 的任何部分,您的树结构得到更新。
应该很容易。无需技能:)
原来我正在寻找的是使用 rootScope 设置 $broadcast 触发器,然后我可以使用 $on 和每个相应范围中的回调函数进行监听。
例如调用保存时有一个回调函数,所以我的编辑指令(在不同的工厂控制器中)可以添加 $rootScope.$broadcast('branch1Reload');到回调,那么该分支的指令只需要一个 $rootscope.$on('branch1Reload', function() { /* do stuff */ ; scope.reload(); });