Javascript 将新对象添加到集合时更新angular treeview指令
我有一个treeview指令作为我的出发点。将对象添加到集合时尝试更新的。我可以更新对象并插入新对象,但是一旦更新了Javascript 将新对象添加到集合时更新angular treeview指令,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我有一个treeview指令作为我的出发点。将对象添加到集合时尝试更新的。我可以更新对象并插入新对象,但是一旦更新了$scoped项,就不会调用treeview指令。 最终使用的数据将来自一个服务,此时我只是使用模拟数据进行测试 最初的收藏是这样的 $scope.myList = { children: [ { name: "Event", children: [
$scoped
项,就不会调用treeview指令。
最终使用的数据将来自一个服务,此时我只是使用模拟数据进行测试
最初的收藏是这样的
$scope.myList = {
children: [
{
name: "Event",
children: [
{
name: "Event Date",
parent:"Event",
children: [
{
name: "2008",
filterType: '_eventStartDate',
parent: 'Event'
},
{
name: "2009",
filterType: '_eventStartDate',
parent: 'Event'
}
]
},
{
name: "Event Attendee",
parent: "Event",
children: [
{
name: "Person 1",
filterType: '_eventAttenddeeName',
parent: 'Event Attendee'
},
{
name: "Person 2",
filterType: '_eventAttenddeeName',
parent: 'Event Attendee'
}
]
}
]
}]
};
var TheOtherCollection = {
children: [
{
name: "A New Event",
children: [
{
name: "The Other Date",
parent: " A New Event",
children: [
{
name: "2010",
FilterType: '_eventStartDate',
Parent: '_event'
},
{
name: "2011",
FilterType: '_eventStartDate',
Parent: '_event'
}
]
}
]
}]
};
这将使用以下指令和html生成带有复选框的树视图
app.directive('tree', function () {
return {
restrict: 'E',
replace: true,
scope: {
t: '=src',
filter: '&'
},
controller: 'treeController',
template: '<ul><branch ng-repeat="c in t.children track by $index" src="c" filter="doSomething(object, isSelected)"></branch></ul>'
};
});
app.directive('branch', function($compile) {
return {
restrict: 'E',
replace: true,
scope: {
b: '=src',
filter: '&',
checked: '=ngModel'
},
template: '<li><input type="checkbox" ng-click="innerCall()" ng-model="b.$$hashKey" ng-change="stateChanged(b.$$hashKey)" ng-hide="visible" /><a>{{ b.name }}</a></li>',
link: function (scope, element, attrs) {
var clicked = '';
var hasChildren = angular.isArray(scope.b.children);
scope.visible = hasChildren;
if (hasChildren) {
element.append('<tree src="b"></tree>');
$compile(element.contents())(scope);
}
element.on('click', function(event) {
event.stopPropagation();
if (hasChildren) {
element.toggleClass('collapsed');
}
});
scope.stateChanged = function(b) {
clicked = b;
};
scope.innerCall = function() {
scope.filter({ object: scope.b, isSelected: clicked });
};
}
};
});
创建新数组并将其添加到子数组中
function nestAssociation(node, oldCollection, newAggregates) {
// var item = fn(oldCollection, node.parent);
var updatedArray = _.concat(oldCollection.children, newAggregates);
console.log(updatedArray);
if (updatedArray != null)
updateMyList(updatedArray);
}
我可以在输出中看到我有一个新对象,但我无法更新树视图。我曾在指令中尝试在指令中的click事件上添加$compile(元素),但由于尚未构建数组,因此没有任何更改
我是否需要向该指令添加$watch?如果需要,在何处或是否有其他方法可以获得该指令以重新呈现和显示新的嵌套集合
更新
根据一些反馈和问题,这里有一个关于这个问题的更多细节。我看到的问题不在指令中,因为在问题周围移动数据是,一旦将数组添加到现有模型中,我就无法让treeview重新渲染。
以下链接显示项目当前的工作状态。
运行chrome dev tools,我可以在输出中看到,选中复选框后模型将更新
当我看到对象被更新时,指令从不更新以显示添加到对象的新数组。这是我需要帮助理解的部分
提前感谢请尝试$scope。$apply()添加后您将函数传递给内部指令(这是最佳实践),但您可以访问
scope.filter
。不doSomethingFunction
。这一个是未定义的
filter=“doSomething(object,isSelected)”
=>
filter=“filter(object,isSelected)”
更新
在树
指令和index.html
视图中,都有相同的treeController
。
这就是导致视图不更新的原因强>
我删除了指令中的一个,否则每个孩子都有一个控制器。您在控制器中看到了良好的console.log消息,但它位于一个指令的控制器中。
您没有访问
index.html
的控制器
然后我修复了过滤器
功能,实现了孩子之间的通信:
添加新的树时,您忘记了传递筛选函数:
element.append(“”)代码>
此外,在父指令模板中,您还需要散列来向函数发送参数:
filter=“filter({object:object,isSelected:isSelected})”
我编辑了您的Plunker,没有使用上面的注释更改代码。
(我不确定你写的不是你想要的,因为你没有评论,我宁愿不修改它,所以你仍然能快速理解你的代码)
但是现在视图正在更新
我认为对你想要的和上面的评论进行一点调试就足够了
编辑2
您忘记返回属性为chrilden
的对象。您返回了一个数组,这导致了问题
function updateMyList(data) {
var transformed = { children : data };
$scope.myList = transformed;
}
这是一个可行的方法。在$scope早期尝试过。$apply()或$scope。$apply(函数(){…})将不起作用,因为函数当前处于$apply()循环中。所以它不能调用新的one@ricrews您可以通过将调用包装到$scope来避免$apply循环问题。$超时调用中的$apply如果您可以创建一个plunkr或codepen,在其中我们可以看到实际问题并在代码中工作,那将是非常棒的(据我所知,链接的codepen只是您的起点)。您可以发布由nestAssociation()
调用的updateMyList
函数的代码吗。我猜这就是您实际将更新后的数组保存在$scope.myList
中的地方。我已经用一个plunker更新了我的问题link@rlcrews我添加了更多信息并添加了一个新的plunker我认为最新的plunker正在工作,请参阅单击的事件。请让我们知道,如果它不是你想要的工作。
function nestAssociation(node, oldCollection, newAggregates) {
// var item = fn(oldCollection, node.parent);
var updatedArray = _.concat(oldCollection.children, newAggregates);
console.log(updatedArray);
if (updatedArray != null)
updateMyList(updatedArray);
}
app.directive('tree', function () {
return {
restrict: 'E',
replace: true,
scope: {
t: '=src',
filter: '&'
},
controller: 'treeController',
template: '<ul>
<branch ng-repeat="c in t.children track by $index"
src="c" filter="filter(object, isSelected)">
</branch>
</ul>'
};
});
app.directive('branch', function($compile) {
return {
restrict: 'E',
replace: true,
scope: {
b: '=src',
filter: '&'
},
template: '<li><input type="checkbox" ng-click="innerCall(b.$$hashKey)" ng-model="isChecked" ng-hide="visible" /><a>{{ b.name }}</a></li>',
link: function (scope, element, attrs) {
scope.isChecked = false;
var hasChildren = angular.isArray(scope.b.children);
scope.visible = hasChildren;
if (hasChildren) {
element.append('<tree src="b"></tree>');
$compile(element.contents())(scope);
}
element.on('click', function(event) {
event.stopPropagation();
if (hasChildren) {
element.toggleClass('collapsed');
}
});
scope.innerCall = function(hash) {
if(scope.isChecked){
scope.filter({ object: scope.b, isSelected: hash });
}
};
}
};
});
function updateMyList(data) {
var transformed = { children : data };
$scope.myList = transformed;
}