2017-07-12 5 views
1

anzeigen Ich habe ein View-Modell, das eine Loaddata-Funktion hat. Es hat keinen Konstruktor. Ich möchte, dass es die loadData-Methode aufruft, wenn das ID-Feld einen Wert hat.Ich kann keine Daten auf einem scheinbar

Das Feld über erhalten:

self.TemplateId = ko.observable($("#InputTemplateId").val()); 

Dann am Ende meines Viewmodels habe ich ein Stück Code, der das überprüft, und rufe meine Ladefunktion:

if (!self.CreateMode()) { 
     self.loadData(); 
    } 

Mein load-Methode ruft meine .Net-WebAPI-Methode auf, die eine leicht komplexe Struktur zurückgibt. Die Struktur ist eine Klasse mit einigen Feldern und einem Array/Liste. Die Elemente in dieser Liste sind einige grundlegende Felder und eine andere Liste/ein anderes Array. Und dann hat dieses Objekt nur ein paar Felder. Also, es sind 3 Level. Ein Objekt mit einer Liste von Objekten und diese Objekte haben jeweils eine andere Liste von Objekten ...

Mein WebAPI-Aufruf funktioniert. Ich habe es debuggt, und die Daten kommen perfekt zurück.

Ich versuche, den Inhalt dieses Aufrufs in ein beobachtbares Objekt namens 'Data' zu laden. Es wurde früher erklärt:

self.Data = ko.observable(); 

es zu laden, und hält alles zu beobachten, ich die Knockout-Mapping-Plugin verwenden.

self.Data(ko.mapping.fromJS(data)); 

Wenn ich auf der Breakpoint, ich sehe, was ich in den beiden Daten (das Ergebnis des API-Aufrufs) erwarten, und self.Data()

enter image description here

self.Data scheint eine beobachtbare Version der Daten sein, die ich geladen habe. Alle Daten sind da, und alles scheint richtig zu sein.

Ich bin in der Lage, den Wert eines der Felder in der Wurzel des Datenobjekts zu alarmieren:

alert(self.Data().Description()); 

Ich bin auch in der Lage ein Feld innerhalb des ersten Eintrags in der Liste zu sehen.

alert(self.Data().PlateTemplateGroups()[0].Description()); 

Dies zeigt mir, dass Daten eine beobachtbare ist und die Daten enthält. Ich denke, ich werde später in der Lage sein, self.Data zurück zu meiner API zu speichern/zu aktualisieren.

Jetzt beginnen die Probleme.

In meiner Ansicht versuche ich ein Feld anzuzeigen, das sich in der Stammklasse meines komplexen Elements befindet. Etwas, das ich gerade oben gemeldet habe.

<input class="form-control" type="text" placeholder="Template Name" data-bind="value: Data.Description"> 

Ich bekomme keinen Fehler. Das Textfeld ist jedoch leer.

Wenn ich den Code für das Eingabefeld zu ändern sein:

data-bind="value: Data().Description()" 

Daten angezeigt werden.Allerdings sitze ich mit einem Fehler in der Konsole:

Uncaught TypeError: Unable to process binding "value: function (){return Data().Description() }" Message: Cannot read property 'Description' of undefined

Ich denke, es ist die Ansicht Belastung durch ist, bevor die Daten aus dem WebAPI Aufruf geladen wird, und deshalb, weil ich ko.mapping bin mit - dem view hat keine Ahnung was Data(). Description() ist ... und es stirbt.

Gibt es einen Weg, um das zu erreichen, was ich versuche? Unten ist das vollständige ViewModel.

Vielleicht ist die Antwort, die Last innerhalb der ready() - Funktion zu tun, und Daten als Parameter übergeben? Ich bin mir nicht sicher, was passiert, wenn ich ein neues Objekt erstellen möchte, aber ich kann dazu kommen.

Außerdem, wenn ich versuche, speichern, stelle ich fest, dass, obwohl ich ein Feld in der Ansicht (Update Beschreibung, zum Beispiel) ändern, die Daten in der beobachteten Ansicht Modell (self.Data) nicht ändern.

+0

von 'Data.Description' Sie wollen die' Data' Eigenschaft in Ihrem * root * View-Modell oder den 'Data' Punkt in * jeder * deiner 'PlateTemplateGroups'? Mit anderen Worten, wo genau (mit welchem ​​Umfang) liegt diese 'Datenbindung = ...'? Haben Sie auch versucht, value: Data() && Data(). Beschreibung && Daten(). Beschreibung() '? – haim770

+0

Sie könnten dies versuchen: ko.mapping.fromJS (Daten, {}, self.Data); (http://knockoutjs.com/documentation/plugin-mapping.html, 'Angabe des Update-Ziels'). –

+0

@JoseLuis - Ich habe das versucht, und ich musste die Klammern von all meinen Bind-Objekten entfernen. Und keine Daten werden in der Ansicht angezeigt. Obwohl diese.Data Daten enthält. Es scheint, der Bildschirm ist vielleicht zu früh verbindlich? – Craig

Antwort

1

Ihr Eingabefeld könnte dies sein:

<div data-bind="with: Data"> 
    <input class="form-control" type="text" placeholder="Template Name" data-bind="value: Description"> 
</div> 

Ich ziehe with als Reiniger und soll die Verwirrung und Fragen stoppen Sie haben wurden.

Der Grund dafür ist, dass der HTML-Code bereits gebunden ist, bevor die Daten geladen werden. Also entweder keine Anwendung Bindungen, bis die Daten geladen:

$.get("/api/PlateTemplate/Get", { id: self.TemplateId() }).done(function (data) { 
     self.Data(ko.mapping.fromJS(data)); 
     ko.applyBindings(self, document.getElementById("container")); 
    }); 

oder wickeln Sie die Vorlage mit einem if, deshalb wird es nicht geben Sie diesen Fehler als Daten undefiniert ursprünglich ist.

Auch wenn Sie wissen, was das Datenmodell sein wird, könnten Sie Daten dazu voreinstellen.

self.Data = ko.observable(new Data()); 

Bewerben Bindungen Methode:

var viewModel = null; 
$(document).ready(function() { 
    viewModel = new PlateTemplateViewModel(); 
    viewModel.loadData(); 
}); 
+0

In meinem Dokument.Ready - sollte ich die ko.ApplyBinding entfernen? Und verschiebe es in meine loadData-Funktion? Wenn ja, wird es nie ausgeführt. – Craig

+0

in Ihrem Dokument ersetzen ersetzen ko.applyBindings (viewModel, document.getElementById ("Container")); mit viewModel.loadData(); –

+0

Verdammt, .. Ich habe das versucht und die gleichen Ergebnisse erhalten. Hinterlegt das ursprüngliche Modell, das ich geladen habe. Nicht das aktualisierte. Diese.Data scheint nicht aktualisiert zu werden, wenn ich Felder bearbeite. – Craig

Verwandte Themen