简体   繁体   中英

Knockout Observable Array of Observable Array

I have passed a model to my View Model from .Net, which is a Object, containing a few fields, and a List, and each of those has another List.

So, an object with a List of Lists.

On my View, I represent this as some data, with a list of Tabs (The first list), and then each tab has a grid of data.

In my Knockout View model, I just have:

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

self.TemplateGroups = ko.observableArray();

So, my main object, with an observable array (the first list). But, the list within that, isn't observable.

So when rendering my tabls, I do:

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

And that renders each tab. And then within each tab, I do this:

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

('Components' is the name of the list within the outer list)

Problem is, on my ClickIt function, I am displaying the Idof the row I clicked, and it works. And then I am just trying to change the 'Description' field of this outer list, but ... it's not a function, so, no observed:

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

}

The alert shows the Id, but error on Description("Craig"), as it's not a function.

How can I make the list, within my ObservableArray, observable?

(To be clearer, my model I pass in is an object, which contains a List called TemplateGroups... and then each item in that list, contains a List called 'Components'. It's the Id of one of those Components that I am displaying, but I need to make that list Observable.

Edit: This seems to be what I am looking for ( http://jsfiddle.net/rniemeyer/bZhCk/ ), but ... I am not defining my array the same way. Instead, they're being passed in from a .Net class (So, converted to JSON, I think). And that .Net class contains a List of another .Net class, which has a List).

Note, My load method:

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

The content of self.TemplateGroups is data.PlateTemplateGroups , that is an array and its content are not observable properties (they are javascript objects).

If you want that this objects in this array become observables, you could use the 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));
    });
}

This way, all properties become observables.

If you need to convert this data to a Json format you could use ko.mapping.toJS() :

ko.mapping.toJS(self.TemplateGroups)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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