gpt4 book ai didi

mvvm - 使用 knockout 映射插件将深度分层的对象映射到自定义类

转载 作者:行者123 更新时间:2023-12-03 11:01:16 25 4
gpt4 key购买 nike

使用 knockout 映射插件 ( http://knockoutjs.com/documentation/plugins-mapping.html ) 可以映射一个深层次的对象吗?

如果我有一个具有多个级别的对象:

var data = {
name: 'Graham',
children: [
{
name: 'Son of Graham',
children: [
{
name: 'Son of Son of Graham',
children: [
{
... and on and on....
}
]

}
]
}
]
}

我如何将它映射到我在 javascript 中的自定义类:
var mapping = {
!! your genius solution goes here !!

!! need to create a myCustomPerson object for Graham which has a child myCustomerPerson object
!! containing "Son of Graham" and that child object contains a child myCustomerPerson
!! object containing "Son of Son of Graham" and on and on....

}

var grahamModel = ko.mapping.fromJS(data, mapping);

function myCustomPerson(name, children)
{
this.Name = ko.observable(name);
this.Children = ko.observableArray(children);
}

映射插件可以递归地将此数据映射到我的自定义对象的层次结构中吗?

最佳答案

像这样( Live copy on js fiddle ):

CSS:

.left {
float: left;
}

.clear {
clear: both;
}​

HTML:
<p>Current:&nbsp;
<a href="#" data-bind="visible: (stack.length > 0), text: selectedNode().name, click: selectParentNode"></a>
<span data-bind="visible: (stack.length <= 0), text: selectedNode().name"></span>
</p>
<p class="left">Children:&nbsp;</p>
<ul class="left" data-bind="template: {name: 'childList', foreach: selectedNode().children}"></ul>

<script type="text/html" id="childList">
<li data-bind="click: function(){nodeViewModel.selectChildNode($data)}">
<a href="#">A${name}</a>
</li>
</script>

<br /><br />
<ul class="clear" data-bind="template: {name: 'backBtn'}"></ul>

<script type="text/html" id="backBtn">
<a href="#" data-bind="visible: $data.selectedNode().back, click: function() { nodeViewModel.selectBackNode($data.selectedNode().back) }">Back</a>
</script>​

JavaScript:
var node = function(config, parent) {
this.parent = parent;
var _this = this;

var mappingOptions = {
children: {
create: function(args) {
return new node(args.data, _this);
}
}
};

ko.mapping.fromJS(config, mappingOptions, this);
};

var myModel = {
node: {
name: "Root",
children: [
{
name: "Child 1",
back: 1,
children: [
{
name: "Child 1_1",
back: 1,
children: [
{
name: "Child 1_1_1",
back: 4,
children: [
]},
{
name: "Child 1_1_2",
back: 2,
children: [
]},
{
name: "Child 1_1_3",
back: 1,
children: [
]}
]}
]},
{
name: "Child 2",
back: 1,
children: [
{
name: "Child 2_1",
back: 1,
children: [
]},
{
name: "Child 2_2",
back: 1,
children: [
]}
]}
]
}
};

var viewModel = {

nodeData: new node(myModel.node, undefined),

selectedNode: ko.observable(myModel.node),

stack: [],

selectBackNode: function(numBack) {

if (this.stack.length >= numBack) {
for (var i = 0; i < numBack - 1; i++) {
this.stack.pop();
}
}
else {
for (var i = 0; i < this.stack.length; i++) {
this.stack.pop();
}
}

this.selectNode( this.stack.pop() );
},

selectParentNode: function() {
if (this.stack.length > 0) {
this.selectNode( this.stack.pop() );
}
},

selectChildNode: function(node) {
this.stack.push(this.selectedNode());
this.selectNode(node);
},

selectNode: function(node) {
this.selectedNode(node);
}

};

window.nodeViewModel = viewModel;
ko.applyBindings(viewModel);​

这个示例只是映射了一组无限嵌套的 JSON 数据,我可以说实际上在应用程序中使用这个确切的代码效果很好。

一些额外的功能,如

selectBackNode 和 selectParentNode

允许您移回树上。

在导航示例时,父标签变成了一个链接以允许上一层,并且一些叶节点有一个后退按钮,允许它们向后移动给定数量的树。

- 编辑 -

如果您的叶节点没有 children 数组,您可能会遇到一个问题,即引入了模型中不存在的额外数据。

关于mvvm - 使用 knockout 映射插件将深度分层的对象映射到自定义类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7499133/

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