2012-11-16 3 views
15

Ich arbeite an einem Rapid-Prototyping-Tool, für die ich die Schnittstelle dynamisch generieren und dynamisch Daten an die erstellten Elemente Daten binden möchte. Das Ansichtsmodell würde in etwa so aussehen:Knockoutjs programmatische Databinding zu generierten Schnittstelle

var viewModel = { 
    vmSchema: { 
      "Id" : "int", 
      "Name" : "string", 
      "UpdatedOn" : "date" 
    }, 
    vmData: { 
      "Id": "123" 
      "Name" : "Bob", 
      "UpdatedOn" : "2012-11-16T00:00:00" 
    } 
} 

Die vmSchema verwendet würden, um die Schnittstellenelemente auf der Grundlage ihrer Art zu schaffen, und dann würde Vmdata auf jene Elemente Databind.

Das Erstellen der Schnittstelle ist kein Problem. Die Herausforderung besteht darin, den vmData mdoel programmatisch an die generierte Schnittstelle zu binden.

Gibt es Werkzeuge oder Techniken, die diese Art von programmatischer Datenbindung ermöglichen?

Antwort

31

Es scheint, dass die Felder und Typen Ihres Modells erst zur Laufzeit bekannt sind. Für diese Art von dynamisch erzeugtem Modell müssten Sie Code schreiben, der seine Eigenschaften in Observable verwandelt, vorausgesetzt, Sie benötigen eine bidirektionale Bindung. Am einfachsten können Sie durch Vmdata laufen und drehen alles in ein ko.observable:

for (var member in viewModel.vmData) { 
    if (viewModel.vmData.hasOwnProperty(member)) { 
     viewModel.vmData[member] = ko.observable(viewModel.vmData[member]); 
    } 
} 

In Bezug auf die Ansicht verbindlich, es hängt davon ab, was „die Erstellung der Interface-Elemente“. Wenn sie den HTML-Elementen zum Zeitpunkt der Erstellung data-bind Attribute hinzufügen können, sollte alles unkompliziert sein: Führen Sie einfach ko.applyBindings aus, sobald die Schnittstelle erstellt und an das DOM angehängt wurde. Wenn Sie aus irgendeinem Grund die data-bind Dekorationen nicht hinzufügen können, können Sie Bindungen manuell mit dem leicht undokumentierten ko.applyBindingsToNode angeben.

// manually specify a binding for an element 
var elm = document.getElementById('some_elm'); 
ko.applyBindingsToNode(elm, { value: viewModel.vmData.id}, viewModel.vmData); 

Das obige entspricht <span class="some_elm" data-bind="value: vmData.id"></span>.

+0

Ich werde knockout auch verwenden, um die Benutzeroberfläche zu generieren, indem ich durch das vmSchema iteriere und bedingte Vorlagen basierend auf dem Typ verwende. Der Trick besteht dann darin, sie programmatisch mit vmData zu verbinden. – dcpar

+1

Danke dafür! Es ist genau das, was ich brauchte, um eine eingebaute Bindung in einem Custom-Binding-Handler einzurichten! – rossisdead

+1

+1 Danke! Ich wollte gerade aufgeben, aber dann fand ich diesen Beitrag. – Laith