简体   繁体   English

淘汰嵌套模型属性

[英]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: 我会说最好定义两个视图模型:

  1. Form , and Form
  2. Section

Your Form will have three kinds of properties: 您的Form将具有三种属性:

  1. Regular ko.observable values, for Id , Name and Title IdNameTitle常规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永远不会改变:您可以通过将其设置为常规字符串来向代码的其他读者发送此信号。

  2. An observableArray for your list of Section s 您的Section s列表的observableArray

  3. A pureComputed for Total that sums up all your Section points 用于TotalpureComputed 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM