gpt4 book ai didi

javascript - 将新对象添加到集合时更新 Angular TreeView 指令

转载 作者:数据小太阳 更新时间:2023-10-29 03:54:56 26 4
gpt4 key购买 nike

我有一个 treeview 指令归功于 http://codepen.io/bachly/pen/KwWrzG作为我的起点。当我将对象添加到集合中时,我正在尝试更新。我可以更新对象并插入新对象,但是一旦更新了 $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 生成带有复选框的 TreeView

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 });
};
}
};
});

然后是html

  <div ng-controller="treeController">
<tree src="myList" iobj="object" filter="doSomething(object, isSelected)"></tree>

<a ng-click="clicked()"> link</a>
</div>

单击复选框时,使用 lodashjs 将新集合添加到现有集合

ng-点击事件

$scope.doSomething = function (object, isSelected) {
if (isSelected) {
var item = object;
console.log(item);
nestAssociation(object, $scope.myList, TheOtherCollection);
}
}

创建新数组并将其添加到子数组中

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);
}

我可以在输出中看到我有一个新对象,但我无法更新 TreeView 。我已经尝试在指令中在指令中的 click 事件上添加一个 $compile(element) 但由于数组尚未构建,因此没有任何变化。

我是否需要向该指令添加一个 $watch?如果需要,我可以从何处获取指令以重新呈现并显示新的嵌套集合?

更新

根据此处的一些反馈和问题,围绕该问题提供了更多详细信息。我看到的问题不在指令中,就围绕问题移动数据而言,一旦将数组添加到现有模型,我就无法让 TreeView 重新呈现。以下链接is a working plunker这显示了项目当前的工作情况。运行 chrome 开发工具我可以在输出中看到模型在选中复选框后更新 enter image description here

虽然我看到对象已更新,但指令从未更新以显示添加到对象的新数组。这是我需要帮助理解的部分。

提前致谢

最佳答案

您将函数传递给内部指令(这是最佳实践),但您可以访问 scope.filter .不是doSomethingFunction .这个是undefined那里。

filter="doSomething(object, isSelected)"
=>
filter="filter(object, isSelected)"

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>'
};
});

下一个:

您永远无法访问 $$ angularJS 中的变量,因为它们是私有(private)的。也许你应该从你的数据库中制作一个...,但是 $$hashkey不过,这似乎是一个简单的解决方案。

checked属性可能会引发错误,因为 ngModel您的树指令模板中不存在。 (在前面至少放一个?)

复选框不能有 $$hashkey 作为模型。
ng-change 和 ng-click 总是会同时被调用,使用最简单的一个。

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 });
}

};
}
};
});

更新

你有相同的treeController在你的tree指令和你的 index.html看法。这就是导致 View 不更新的原因!

我在你的指令中删除了那个,否则你会为每个 child 都有一个 Controller 。
您在 Controller 中看到了良好的 console.log 消息,但它在一个 Controller 中用于 ONE 指令。
您没有访问 index.html 的 Controller .

然后我修复了 filter child 之间的功能交流:

当你追加新的tree时,你忘了传达过滤功能的:

element.append('<tree src="b" filter="filter({ object: object, isSelected: isSelected })"></tree>');

此外,在您的父指令模板中,您还需要散列来向函数发送参数:
filter="filter({ object: object, isSelected: isSelected })"

我编辑了你的 Plunker HERE无需使用我所做的上述评论更改代码。
(我不确定你写的是不是你想要的,因为你没有评论我宁愿不改变它所以你仍然可以快速理解你的代码)
但是 View 现在正在更新!
我认为根据您的需要进行一些调试,上面的评论就足够了。

编辑 2
您忘记返回属性为 chrilden 的对象.您返回了一个数组,这导致了问题。

function updateMyList(data) {
var transformed = { children : data };
$scope.myList = transformed;
}

这是一个有效的 PLUNKER .

关于javascript - 将新对象添加到集合时更新 Angular TreeView 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35232872/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com