2017-07-09 4 views
1

Ich habe ein Modell zu meinem View Model von .Net, das ein Objekt ist, das ein paar Felder und eine Liste enthält, und jeder von denen hat eine andere Liste.Knockout Observable Array von Observable Array

Also, ein Objekt mit einer Liste von Listen.

In meiner Ansicht, ich repräsentiere dies als einige Daten, mit einer Liste von Tabs (Die erste Liste), und dann hat jede Registerkarte ein Raster von Daten.

In meinem Knockout Ansicht Modell, ich habe nur:

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

self.TemplateGroups = ko.observableArray(); 

Also, mein Hauptziel, mit einer beobachtbaren Array (die erste Liste). Aber die Liste darin ist nicht beobachtbar.

Also, wenn mein tabls Rendering, das tue ich:

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

Und das macht jeden Registerkarte. Und dann in jedem Register, ich dies tun:

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

(‚Komponenten‘ ist der Name der Liste innerhalb der äußeren Liste)

Problem ist, auf meine ClickIt Funktion, bin ich die Anzeige der Idof die Zeile, die ich geklickt habe, und es funktioniert. Und dann bin ich nur versucht, das Feld ‚Beschreibung‘ diese äußeren Liste zu ändern, aber ... es ist keine Funktion, so, nicht beobachtet:

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

} 

Die Warnung zeigt die Id, aber Fehler auf Beschreibung ("Craig"), da es keine Funktion ist.

Wie kann ich die Liste innerhalb meines ObservableArray beobachtbar machen?

(Um es deutlicher zu machen, mein Modell, das ich übergebe, ist ein Objekt, das eine Liste namens TemplateGroups enthält ... und dann enthält jedes Element in dieser Liste eine Liste mit dem Namen 'Components'. Es ist die Id eines solchen Komponenten, die ich zeige, aber ich muss diese Liste Observable machen.

Edit: Dies scheint, was ich suche (http://jsfiddle.net/rniemeyer/bZhCk/), aber ... Ich definiere meine Array nicht auf die gleiche Weise. Stattdessen Sie werden von einer .Net-Klasse (also in JSON konvertiert, glaube ich) weitergegeben. Und diese .Net-Klasse enthält eine Liste einer anderen .Net-Klasse, die eine Liste hat).

Hinweis, My Last Methode:

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

Der Inhalt 'self.TemplateGroups' nicht beobachtbar sind.Sie sind einfache JavaScript-Objekte. Vielleicht könnten Sie das Mapping Plugin (http://knockoutjs.com/documentation/plugin-mapping.html) verwenden: 'self.TemplateGroups (ko.mapping.fromJS (data.PlateTemplateGroups));', in Ihren 'self.loadData '. Auf diese Weise werden alle Eigenschaften beobachtbar. –

+0

@JoseLuis - Perfekt! Wow, vielen Dank! Das hat perfekt funktioniert. Wenn ich meine View Model-Daten wieder in derselben Struktur bereitstellen möchte, gibt es eine Möglichkeit, das View Model mit den aktualisierten Werten wieder der gleichen Struktur zuzuordnen, in der ich es erhalten habe? Also wie ein "ToJSON" oder so? auch, wenn Sie eine Antwort erstellen können, und ich kann es akzeptieren. Vielen Dank! (nochmal!) – Craig

Antwort

1

Der Gehalt an self.TemplateGroupsdata.PlateTemplateGroups ist, ist, dass eine Anordnung und ihr Inhalt nicht beobachtbaren Eigenschaften (sie JavaScript-Objekte sind).

Wenn Sie, dass diese Objekte Observablen in diesem Array wollen werden, können Sie die Mapping Plugin verwenden:

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

diese Weise werden alle Eigenschaften werden Observablen.

Wenn Sie diese Daten in ein JSON-Format konvertieren können Sie ko.mapping.toJS() verwenden:

ko.mapping.toJS(self.TemplateGroups) 
+0

Danke @JoseLuis - Zurück zu sparen scheint jedoch ein Problem zu sein. Ist es so einfach, einfach ko.mapping.toJS (self) zu verwenden, um alle Daten im Ansichtsmodell, einschließlich der Liste und der Liste, an meine WebAPI-Funktion im selben Format zu senden, an das sie an das Ansichtsmodell übergeben wurde ? Oder muss ich ein bisschen mehr tun? Da bekomme ich Fehler, wenn ich die toJS-Methode versuche. Es kämpft mit meinen Klicks/Speicherfunktionen. – Craig

+0

@Craig Ich weiß nicht, wenn ich ein JSON sende, mache ich das: 'var unmapped = ko.mapping.toJS (self); var unmappedJSON = ko.toJSON (nicht zugeordnet); 'Dieser Code wird in meinem ViewModel in eine Funktion umgewandelt, deshalb benutze ich' self'. –

+0

Dies ist ein Beispiel: https://codepen.io/anon/pen/QgzqVe –

Verwandte Themen