【问题标题】:Knockout Observable Array of Observable ArrayObservable Array的Knockout Observable Array
【发布时间】:2017-12-13 03:10:03
【问题描述】:

我已将一个模型从 .Net 传递给我的视图模型,它是一个对象,包含一些字段和一个列表,其中每个都有另一个列表。

所以,一个具有列表列表的对象。

在我的视图中,我将其表示为一些数据,带有一个选项卡列表(第一个列表),然后每个选项卡都有一个数据网格。

在我的 Knockout View 模型中,我只有:

self.Name = ko.observable("");
self.Width = ko.observable(0);
self.Height = ko.observable(0);

self.TemplateGroups = ko.observableArray();

所以,我的主要对象,带有一个可观察数组(第一个列表)。但是,其中的列表是不可观察的。

所以在渲染我的表格时,我会这样做:

<div class="tab-content" data-bind="foreach: TemplateGroups">

这会呈现每个选项卡。然后在每个选项卡中,我这样做:

<tbody data-bind="foreach: $data.Components">
      <tr  style="cursor: pointer" data-bind="click: $parents[1].ClickedIt">

('Components'是外部列表中的列表名称)

问题是,在我的 ClickIt 函数中,我正在显示我单击的行的 Idof,并且它可以工作。然后我只是想改变这个外部列表的“描述”字段,但是......它不是一个函数,所以,没有观察到:

self.ClickedIt = function () {
    alert(this.Id);
    this.Description("Craig");

}

警报显示 ID,但在 Description("Craig") 上显示错误,因为它不是函数。

如何使我的 ObservableArray 中的列表可观察?

(更清楚地说,我传入的模型是一个对象,其中包含一个名为 TemplateGroups 的列表...然后该列表中的每个项目都包含一个名为“组件”的列表。它是其中一个组件的 ID我正在显示,但我需要使该列表可观察。

编辑:这似乎是我正在寻找的 (http://jsfiddle.net/rniemeyer/bZhCk/),但是......我没有以同样的方式定义我的数组。相反,它们是从 .Net 类传入的(所以,我认为,转换为 JSON)。并且那个 .Net 类包含另一个 .Net 类的 List,它有一个 List)。

注意,我的加载方法:

self.loadData = function () {
        $.get("/api/PlateTemplate/Get", { id: self.TemplateId() }).done(function (data) {
            self.Name(data.Description);
            self.Width(data.Width);
            self.Height(data.Height);
            self.TemplateGroups(data.PlateTemplateGroups);
        });
    }

【问题讨论】:

  • self.TemplateGroups 的内容是不可观察的。它们是普通的 javascript 对象。也许您可以在您的self.loadData 中使用映射插件 (knockoutjs.com/documentation/plugins-mapping.html):self.TemplateGroups(ko.mapping.fromJS(data.PlateTemplateGroups));。这样,所有属性都变得可观察。
  • @JoseLuis - 完美!哇,非常感谢!这非常有效。当我想将我的视图模型数据发布回相同的结构时,有没有办法将视图模型映射回我收到它的相同结构,并使用更新的值?那么,像“toJSON”之类的?另外,如果您可以创建一个答案,我可以接受。谢谢! (再次!)

标签: javascript arrays list knockout.js


【解决方案1】:

self.TemplateGroups 的内容是data.PlateTemplateGroups,即一个数组,其内容不是可观察的属性(它们是 javascript 对象)。

如果你想让这个数组中的这个对象成为可观察对象,你可以使用Mapping Plugin

self.loadData = function () {
    $.get("/api/PlateTemplate/Get", { id: self.TemplateId() }).done(function (data) {
        self.Name(data.Description);
        self.Width(data.Width);
        self.Height(data.Height);
        self.TemplateGroups(
          ko.mapping.fromJS(     //   <--- new
             data.PlateTemplateGrou‌​ps));
    });
}

这样,所有的属性都变成了 observables。

如果您需要将此数据转换为 Json 格式,您可以使用 ko.mapping.toJS():

ko.mapping.toJS(self.TemplateGroups)

【讨论】:

  • 谢谢@JoseLuis - 虽然保存回来似乎是一个问题。是否像使用 ko.mapping.toJS(self) 将视图模型中的所有数据(包括 List 和 List 的列表)以与传递给视图模型相同的格式发送回我的 WebAPI 函数一样简单?还是我需要做更多的事情?当我尝试 toJS 方法时遇到错误。它与我的点击/保存功能作斗争。
  • @Craig 我不知道,当我发送 JSON 时,我会这样做:var unmapped = ko.mapping.toJS(self); var unmappedJSON = ko.toJSON(unmapped); 此代码进入我的 ViewModel 中的一个函数,因此我使用 self
猜你喜欢
  • 2013-04-22
  • 1970-01-01
  • 2014-10-01
  • 2014-11-27
  • 2013-03-11
  • 1970-01-01
  • 2013-11-10
  • 2012-06-14
  • 2015-02-03
相关资源
最近更新 更多