[英]Knockout nested model properties
I need a feature like a repeating table in my web form and need to store my data in a JSON format like this: 我需要Web表单中的重复表之类的功能,并且需要以JSON格式存储数据,如下所示:
[
{
"id": 1, "name": "T01", "title": "T01 form title", "totalPoints": "total of all points for sections below",
"sections":
[
{ "section": "First section", "point": 4 },
{ "section": "Second section", "point": 5 }
]
},
{
"id": 2, "name": "T02", "title": "T02 form title", "totalPoints": "total of all points for sections below",
"sections":
[
{ "section": "First section", "point": 4 },
{ "section": "Second section", "point": 5 }
]
}
] ]
I'm using knockout and I implemented top level of the structure below, but struggling with a nested sections. 我正在使用淘汰赛,并实现了下面结构的顶层,但在嵌套部分中苦苦挣扎。
Here is my attempts to structure my Model, please advise what option to use, or if this incorrect, please advise the right option: 这是我尝试构建模型的尝试,请告知要使用的选项,否则,请告知正确的选项:
function Form(data)
{
this.Id = ko.observable(data.Id);
this.Name = ko.observable(data.Name);
this.Title = ko.observable(data.Title);
this.Total = ko.observable(data.Total);
// Option 1, like an array
this.Sections = ko.observableArray([
{
Section: data.Section,
Point: data.Total
}
]);
// Option 2, like a function
function Sections(data) {
this.Section = ko.observable(data.Section),
this.Point = ko.observable(data.Point)
}
}
Later I push this data as a model to observable array like this, again I can push the top level, but couldn't nested properties: 稍后,我将这些数据作为模型推入这样的可观察数组中,再次可以推到顶层,但不能嵌套属性:
self.addForm = function () {
self.forms.push(
new Form({
Id: this.id(),
Name: this.name(),
Title: this.title(),
Total: function() // TODO
// Sections nested properties implementation
})
);
self.name("");
};
I'd say it's best to define two viewmodels: 我会说最好定义两个视图模型:
Form
, and Form
和 Section
Your Form
will have three kinds of properties: 您的
Form
将具有三种属性:
Regular ko.observable
values, for Id
, Name
and Title
Id
, Name
和Title
常规ko.observable
值
Note: If some of those are static, it's best to not make them observable. 注意:如果其中一些是静态的,最好不要使它们可观察。 I can imagine the
Id
will never change: you can signal this to other readers of your code by making it a regular string. 我可以想象
Id
永远不会改变:您可以通过将其设置为常规字符串来向代码的其他读者发送此信号。
An observableArray
for your list of Section
s 您的
Section
s列表的observableArray
pureComputed
for Total
that sums up all your Section
points Total
的pureComputed
for Total
总结了您所有的Section
点 function Section(points, title) { // TODO: check if you need these to be observable this.points = points; this.title = title; }; // Create a new Section from a plain object Section.fromData = function(data) { return new Section(data.point, data.section); }; function Form(id, name, title, sections) { this.id = ko.observable(id); this.name = ko.observable(name); this.title = ko.observable(title); // Map using our static constructor helper this.sections = ko.observableArray( sections.map(Section.fromData) ); this.total = ko.pureComputed(function() { return this.sections().reduce(function(sum, section) { return sum + section.points; }, 0); }, this); } // A helper to get from your data object to a new VM Form.fromData = function(data) { return new Form(data.id, data.name, data.title, data.sections); } // Apply bindings ko.applyBindings({ forms: getTestData().map(Form.fromData) }); // Your test data function getTestData() { return [{ "id": 1, "name": "T01", "title": "T01 form title", "totalPoints": "total of all points for sections below", "sections": [{ "section": "First section", "point": 4 }, { "section": "Second section", "point": 5 } ] }, { "id": 2, "name": "T02", "title": "T02 form title", "totalPoints": "total of all points for sections below", "sections": [{ "section": "First section", "point": 4 }, { "section": "Second section", "point": 5 } ] } ] };
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <ul data-bind="foreach: forms"> <li> <p data-bind="text: title"></p> <ul data-bind="foreach: sections"> <li> <span data-bind="text: title"></span> ( <span data-bind="text: points"></span>) </li> </ul> <span data-bind="text: 'total: (' + total()"></span>) </li> </ul>
The Section
class is a bit plain; Section
类有点简单; if you don't have additional requirements you could choose to use plain objects instead. 如果您没有其他要求,则可以选择使用普通对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.