gpt4 book ai didi

javascript - n 级深度复选框树行为

转载 作者:行者123 更新时间:2023-11-30 13:08:17 25 4
gpt4 key购买 nike

我有一个使用 knockout 实现的 n 级复选框树,其中父级复选框的选择应该选择它的子级(而不是相反)并且一旦提交数据,所选元素的 id 应该转换为 JSON 以发送到服务器。

我不知道如何处理单向复选框关系,也不知道如何以这种方式过滤我的最终 json:

  1. 如果选择了一个父项(因为这意味着它的所有子项也被选中)不在 json 中发送其子项 ID

  2. 如何在仅选择一个或几个 child 时不发送 parent ID。

列表项的模型是:

marketingListsItem = function (data, parent) {
var self = this;
self.Name = ko.observable(data.Name);
self.Selected = ko.observable(data.Selected);
self.Parent = ko.observable(parent);
self.Children = ko.observableArray([]);
self.Id = ko.observable(data.Id);
self.DateAdded = ko.observable(new Date(data.DateAdded));
self.DateModified = ko.observable(data.DateModified);
if (data.Children) {
ko.utils.arrayForEach(data.Children, function (child) {
self.Children.push(new marketingListsItem(child, this));
}.bind(this));
};
}

这是 View 模型部分:

marketingListsViewModel = {
marketingLists: mapping.fromJS([]),
originatorConnectionName: ko.observable(''),
selectedMarketingListIds: ko.observableArray([])
},
init = function (connectionId, connectionName) {
marketingListsViewModel.originatorConnectionName(connectionName);
marketingListsViewModel.getFieldMapping = function () {
require(['mods/fieldmapping'], function (fieldmapping) {
fieldmapping.init(connectionId, connectionName);
});
};
// Here I only managed to filter the parent level selections
marketingListsViewModel.selectedLists = ko.computed(function () {
return ko.utils.arrayFilter(marketingListsViewModel.marketingLists(), function (item) {
return item.Selected() == true;
});
});
marketingListsViewModel.saveMarketingListChanges = function () {
// Which I can filter my JSON to include them but the children are missing
var latestMarketingListChanges = ko.toJSON(marketingListsViewModel.selectedLists, ["Id"]);
console.log(latestMarketingListChanges);
amplify.request("updateExistingMarketingLists", { cid: connectionId, ResponseEntity: { "id": connectionId, "selectedMarketListIds": latestMarketingListChanges } },
function (data) {
console.log(data);
});
}
amplify.request("getExistingMarketingLists", { cid: connectionId }, function (data) {
showMarketingLists();
mapping.fromJS(data.ResponseEntity, dataMappingOptions, marketingListsViewModel.marketingLists);
ko.applyBindings(marketingListsViewModel, $('#marketingLists')[0]);
});
};

最后是 View :

<div id="marketingListsContainer">
<ul data-bind="template: {name: 'itemTmpl' , foreach: marketingLists}"></ul>
<script id="itemTmpl" type="text/html">
<li>
<label><input type="checkbox" data-bind="checked: Selected" /><span data-bind='text: Name'></span></label>
<ul data-bind="template: { name: 'itemTmpl', foreach: Children }" class="childList"></ul>
</script>
</div>
<a class="s_button modalClose right" href="#"><span data-bind="click: saveMarketingListChanges">Save and close</span></a><br>

最佳答案

感谢您的回答。问题是,如果您的解决方案现在已经通过服务器的数据检查了父项,那么它的子项的检查值不会发生变化。

我已将以下内容添加到模型中以解决此问题:

self.sync = ko.computed(function () {
return self.Selected.valueHasMutated();
});

对于那些稍后会找到这篇文章并且可能想看看最终结果是什么的人:

    define('mods/marketinglists', ["knockout", "libs/knockout.mapping", "libs/knockout.validation", "datacontext", "mods/campaigner", "text!templates/marketinglists.html", "text!styles/marketinglists.css"],
function (ko, mapping, validation, datacontext, campaigner, html, css) {
'use strict';
var
marketingListsItem = function (data, parent) {
var self = this;
self.Name = ko.observable(data.Name);
self.Selected = ko.observable(data.Selected);
self.Parent = ko.observable(parent);
self.Children = ko.observableArray([]);
self.Id = ko.observable(data.Id);
self.DateAdded = ko.observable(new Date(data.DateAdded));
self.DateModified = ko.observable(data.DateModified);
// If node contains children define each one as a marketingListItem in itself
// and bind it to the the model
if (data.Children) {
ko.utils.arrayForEach(data.Children, function (child) {
self.Children.push(new marketingListsItem(child, this));
}.bind(this));
};
// Watch for value changes in parent and check children
// if the parent was checked
self.Selected.subscribe(function (newValue) {
if (newValue === true) {
for (var i = 0; i < self.Children().length; i++) {
self.Children()[i].Selected(true);
}
}
else {
if (self.Parent() != null) { self.Parent().Selected(false); }
}
});
// Make sure subscribers have been notified when needed
self.sync = ko.computed(function () {
return self.Selected.valueHasMutated();
});
},
dataMappingOptions = {
key: function (data) {
return data.Id;
},
create: function (options) {
return new marketingListsItem(options.data, null);
}
},
showMarketingLists = function () {
campaigner.addStylesToHead(css);
campaigner.addModalWindow(html, {
windowSource: "inline",
width: 700,
height: '340'
});
},
marketingListsViewModel = {},
init = function (connectionId, connectionName) {
// Define marketingLists as an observable array from JS object
marketingListsViewModel.marketingLists = mapping.fromJS([]);
marketingListsViewModel.originatorConnectionName = ko.observable('');
// Set the name for the marketing list
marketingListsViewModel.originatorConnectionName(connectionName);
marketingListsViewModel.getFieldMapping = function () {
require(['mods/fieldmapping'], function (fieldmapping) {
fieldmapping.init(connectionId, connectionName);
});
};
marketingListsViewModel.selectedLists = ko.computed(function () {
var selectedItems = [];
ko.utils.arrayFilter(
marketingListsViewModel.marketingLists(),
function (item) {
// If a parent a selected its being collected
if (item.Selected() == true) selectedItems.push(item);
else {
// If a child is slected it is collected
ko.utils.arrayForEach(item.Children(), function (child) {
if (child.Selected()) selectedItems.push(child);
else {
ko.utils.arrayForEach(child.Children(),
// Finally if children's child is selected its collected
function (childChildren) {
if (childChildren.Selected())
selectedItems.push(childChildren);
});
}
})
}
});
return selectedItems;
});
marketingListsViewModel.saveMarketingListChanges = function () {
// Pick only the selected elements and parse only the Id
var latestMarketingListChanges = ko.toJSON
(marketingListsViewModel.selectedLists,
["Id"]);
console.log(latestMarketingListChanges);
// Send the latest marketing lists changes Ids to the server
amplify.request("updateExistingMarketingLists",
{
cid: connectionId,
ResponseEntity:
{
"id": connectionId,
"selectedMarketListIds": latestMarketingListChanges
}
},
function (data) {
console.log(data);
});
}
amplify.request("getExistingMarketingLists", { cid: connectionId },
function (data) {
showMarketingLists();
mapping.fromJS(
data.ResponseEntity,
dataMappingOptions,
marketingListsViewModel.marketingLists);

ko.applyBindings(marketingListsViewModel, $('#marketingLists')[0]);
});
};
return {
init: init,
marketingListsViewModel: marketingListsViewModel,
html: html,
css: css
}
});

有了这个观点:

<div id="marketingListsContainer">
<ul data-bind="template: {name: 'itemTmpl' , foreach: marketingLists}"></ul>
<script id="itemTmpl" type="text/html">
<li>
<!-- ko if: $data.Parent -->
(my parent is: <span data-bind="text: $data.Parent().Name"></span>)
<!-- /ko -->
<label><input type="checkbox" data-bind="checked: Selected" /><span data-bind='text: Name'></span></label>
<ul data-bind="template: { name: 'itemTmpl', foreach: Children }" class="childList"></ul>
</script>
</div>
<a class="s_button modalClose right" href="#"><span data-bind="click: saveMarketingListChanges">Save and close</span></a><br>

关于javascript - n 级深度复选框树行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14857620/

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