Knockout嵌套模型属性

时间:2017-04-08 18:32:05

标签: json knockout.js

我需要在网络表单中使用像重复表这样的功能,并且需要以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 }
        ]
  }

我使用了淘汰赛并且我实现了下面结构的顶层,但是在嵌套部分中挣扎。

以下是我尝试构建我的模型,请告知使用哪个选项,或者如果这不正确,请告知正确的选项:

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

后来我把这个数据作为模型推送到像这样的可观察数组,我再次推动顶级,但不能嵌套属性:

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

1 个答案:

答案 0 :(得分:0)

我认为最好定义两个viewmodel:

  1. Form
  2. Section
  3. 您的Form将有三种属性:

    1. 常规ko.observable值,适用于IdNameTitle

      注意:如果其中一些是静态的,最好不要让它们可观察。我可以想象Id永远不会改变:您可以通过将其作为常规字符串向其他读者发出信号。

    2. observableArray

    3. 列表Section
    4. pureComputed 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 } ] } ] };
    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>
      Section

      echo "|" > filename pipe = $(cat filename) ps -ef somethinghere($(pipe)) grep java 类有点简单;如果您没有其他要求,可以选择使用普通对象。