2012-11-18 10 views
10

Ich bin neu zu knockout.js und ich versuche, auf das folgende Objekt zu binden, um einen Benutzer darstellt:Knockout.js: Die Bindung an komplexem Objekt

{ 
    "$id": "1", 
    "$values": [ 
     { 
      "$id": "2", 
      "Locations": { 
       "$id": "3", 
       "$values": [] 
      }, 
      "Photos": { 
       "$id": "4", 
       "$values": [] 
      }, 
      "UserId": 1, 
      "Name": "Test User" 
     } 
    ] 
} 

Ein Benutzer oder mehr Stellen Null kann und null oder mehr Fotos.

Die Ansicht Modell:

function UsersViewModel() { 
    var self = this; 
    self.users = ko.observableArray(); 

    var baseUri = 'http://localhost:46241/api/users'; 

    $.getJSON(baseUri, function (data) { 
     self.users = data; 
    }); 
} 

$(document).ready(function() { 
    ko.applyBindings(new UsersViewModel()); 
}) 

Die HTML folgende Bindung enthält:

<ul id="update-users" data-bind="foreach: users"> 
    <li> 
      <div><div class="item">User ID</div> 
       <input type="text" data-bind="value: $data.UserId" /> 
      </div>     
      <div><div class="item">Name</div> 
       <input type="text" data-bind="value: $data.Name" /> 
      </div>     
    </li> 
</ul> 

Bin ich flach heraus diese falsch gemacht? Oder verweisen die Objektreferenzen des Benutzers auf Locations und Fotos möglicherweise die Bindung?

+0

UserId und Namen kommen unter dem Teil "$ values" des Objekts - den Sie nicht in Ihre Bindung aufnehmen. Die Tatsache, dass $ Werte mit einem $ beginnt, könnte Sie mit Knockout in Schwierigkeiten bringen. Wenn Sie kontrollieren, wie das Objekt generiert wird, wäre es wert, die $ s loszuwerden, um es ein wenig aufzuräumen. –

+0

Ist Ihr self.users = Daten funktionieren gut? Ich sehe nicht das Schreiben der $ Werte-Array in Ihre beobachtbare Array – ryadavilli

Antwort

17

Bin ich es nicht richtig?

Ja. Sie sind Ihre observableArray im JSON-Rückruf überschreiben, so dass es zu zerstören:

$.getJSON(baseUri, function (data) { 
    self.users = data; 
}); 

Im Allgemeinen Knockout Observablen zugewiesen dies mögen:

$.getJSON(baseUri, function (data) { 
    self.users(data.$values); 
}); 

Beachten Sie, dass in Ihrem Fall data.$values scheint zu enthalten das eigentliche Array, nicht data selbst.

Dies würde für Ihren Fall funktionieren, aber es nutzt nicht Knockout zu seinem vollen Potenzial.

Die mapping plugin wurde für genau diesen Fall erstellt. Es durchläuft rekursiv ein komplexes Objekt und wandelt all seine Eigenschaften in Observable und alle enthaltenen Arrays in beobachtbare Arrays um. Dies gibt Ihnen eine feinkörnige Kontrolle über den Zustand des Objekts, so dass Sie jede Änderung überwachen können.

Es ermöglicht auch teilweise Updates: Nehmen wir an, Sie erhalten eine Liste der Benutzer vom Server und Ihr Ansichtsmodell hat bereits die Hälfte von ihnen. Das Mapping-Plugin kann nur diejenigen zu Ihrem View-Modell hinzufügen, die fehlen, und entsprechende Änderungen an den vorhandenen vornehmen. Lesen Sie die "Advanced usage" section in der Dokumentation, wenn Sie wissen möchten, wie.


Angenommen, Sie eine Reihe von Benutzerobjekten vom Server erhalten und die Mapping-Plugin verwenden, dann würde Ihre Bindung wie folgt aussehen:

<ul id="update-users" data-bind="foreach: users"> 
    <li> 
      <div><div class="item">User ID</div> 
       <input type="text" data-bind="value: UserId" /> 
      </div>     
      <div><div class="item">Name</div> 
       <input type="text" data-bind="value: Name" /> 
      </div> 
      <ul class="photos" data-bind="foreach: Photos.$values"> 
       <!-- ... --> 
      <ul> 
    </li> 
</ul> 

Auf einem allgemeinen Hinweis, Kommentar @ Greg Smith ist richtig . Versuchen Sie, die $ in den Objektschlüsseln zu verlieren, könnten sie mit speziellen Variablen in Knockout zu irgendeinem Zeitpunkt kollidieren. Sie könnten sie beispielsweise durch Unterstriche ersetzen.

Auf einer allgemeineren Note, würde ich versuchen, das Ganze in Ihrem JSON $id/$values Begriff abzustreifen, wenn ich du wäre, scheint es keinen Zweck zu dienen:

[ 
    { 
     "Locations": [], 
     "Photos": [], 
     "UserId": 1, 
     "Name": "Test User" 
    } 
] 
+0

+1 für den Crash-Kurs in Knockout JS – ryadavilli

+0

Danke, das hilft wirklich viel. Ich werde das Mapping-Plugin ausprobieren, das eine Menge schweres Heben zu machen scheint. Was die Formatierung des JSON betrifft, wird dies von JSON.NET aus dem Entity Framework-Objekt generiert. Wie würde ich die $ id/$ values-Formatierung entfernen? – verbose

+0

@verbose Ich weiß es nicht, aber das ist gutes Material für eine andere Frage. Es scheint sogar, dass niemand das vorher gefragt hatte. – Tomalak

Verwandte Themen