Bindet an ein Nicht-DOM-UI-Element

8

Ich verwende die fantastische knockout.js, um ViewModel-Eigenschaften an das DOM zu binden. Jetzt wird ein Teil meiner GUI auf einem Canvas-Element gerendert. Ich verwende fabric.js, um die Elemente auf der Leinwand zu zeichnen. Da diese Elemente nicht Teil des Doms sind (sie sind Wrapper um Canvas-Zeichnungsmethoden), kann ich Knockout nicht verwenden, um an sie zu binden. Trotzdem muss ich ihre Position / Farbe / Label im ViewModel verfolgen.

Ich würde denken, ich könnte eine benutzerdefinierte Bindung für jeden der Fabric-Primitivtypen erstellen und sie dann wie einen Dom-Knoten binden. Eine benutzerdefinierte Bindung erwartet jedoch ein DOM-Element als seinen ersten Parameter. Zweitens kann ich (einfach) keine Bindung programmatisch hinzufügen. Ich muss dazu in der Lage sein, da ich die Bindungen nicht in HTML schreiben kann.

Ich denke immer noch darüber nach, aber ich bleibe irgendwie für den Moment fest. Irgendwelche Ideen?

    
bertvh 25.07.2014, 16:10
quelle

3 Antworten

4

Benutzerdefinierte Bindungen werden innerhalb von berechneten Observablen implementiert, so dass Abhängigkeiten verfolgt werden und die Funktionalität update erneut ausgelöst werden kann.

Es klingt, als würden Sie für Ihre Funktionalität erwägen, berechnete Observables zu verwenden, die Ihre Objekte verfolgen, auf Abhängigkeiten zugreifen und alle notwendigen Updates / API-Aufrufe durchführen.

Ich habe bisher noch keinen Stoff verwendet, aber hier wäre ein Take, bei dem Sie ein Ansichtsmodell definieren, um ein Rechteck darzustellen und ein berechnetes Objekt zu erstellen, um das Stoffobjekt kontinuierlich zu aktualisieren, wenn sich Werte ändern.

%Vor%

Noch eine kurze Idee, wenn Sie lieber einige der Fabric / Canvas-Aufrufe aus Ihrem View-Modell heraushalten möchten (würde ich wahrscheinlich). Sie könnten eine fabric -Bindung erstellen, die ein Array von Shapes in die Zeichenfläche aufnimmt. Sie würden auch einen Handler übergeben, der die Params abruft, um an sie zu übergeben. Die Bindung erstellt dann die Form, fügt sie der Zeichenfläche hinzu und erstellt dann eine Berechnung, um die Form bei Änderungen zu aktualisieren. Etwas wie:

%Vor%

Sie könnten es auf einer Leinwand wie:

platzieren %Vor%

An diesem Punkt könnte das Ansichtsmodell ziemlich vereinfacht werden, um nur die Daten des Rechtecks ​​darzustellen. Probe hier: Ссылка

    
RP Niemeyer 26.07.2014, 03:03
quelle
0

Ich habe ein ähnliches Problem in meinem Hobby-Projekt, Ссылка ... Ich muss ein Array von Wegpunkten auf eine Karte und ich binden kann es nicht direkt über KO tun, da die Wegpunkte in OpenLayers SVG-Layern verborgen sind. Also verwende ich eine Subskriptionsfunktion innerhalb dieses Musters:

Zuerst ein Ansichtsmodell für die Dinge, die du anzeigst, für mich Wegpunkte, für deine Elemente; grob -

%Vor%

Zweitens, ein Ansichtsmodell, das eine Liste dieser Dinge enthält:

%Vor%

Dann etwas Logik, um Ihre Elemente von Ihrem Webservice in das Ansichtsmodell zu laden, ungefähr:

%Vor%

Es klingt, als ob Sie dieses Bit sortiert haben; Ziel ist es, eine Liste von Elementen zu erhalten, die in einem ObservableArray enthalten sind. Sie können es dann abonnieren und Fabric arbeiten; Es gibt eine Menge Pseudo-Code in diesem nächsten Bit!

%Vor%

Dies ist zwar nicht besonders ausgefeilt, bedeutet aber, dass sich Ihre Änderungen sofort in Ihrer Zeichenfläche widerspiegeln, wenn sich Ihre Daten ändern und sich die Liste der Elemente ändert, indem KO die Subskriptionsfunktion aufruft. Die "Synchronisation" zwischen der neuen Liste von Elementen und dem, was bereits auf der Leinwand ist, ist ziemlich grob: einfach alles zerstören und die gesamte Liste neu darstellen. Dies ist für mich mit meinen Wegpunkten in Ordnung, könnte aber für Sie zu teuer sein.

    
sifriday 26.07.2014 11:16
quelle
0

Ich war daran interessiert, auf diese Frage zu stoßen, da ich auch versucht habe, die Objekte von fabric.js in das Knockout-Modell zu integrieren - ich bin sicher, dass es keine einzige offensichtliche Antwort gibt. Hier ist ein Beispiel, das meine neuesten Gedanken zeigt: Ссылка Es verfügt über eine bidirektionale Datenbindung zwischen DOM-Objekten (Textfeldern) und dem aktuell ausgewählten Canvas-Objekt.

HTML:

%Vor%

Javascript:

%Vor%

Ein paar Dinge zu beachten:

  • Ich erstelle eine ko.observable und mache eine manuelle Subskription, um die Fabric-Objekte zu aktualisieren
  • Ich habe einen Fabric-Event-Handler eingerichtet, der die ko.observable für die Objektauswahl / -änderung aktualisiert. Ich musste nicht an etwas anderes als das aktuell ausgewählte Objekt binden.
  • Ich musste aufgeschobene Updates verwenden, um zyklische Updates zu vermeiden (Fabric Updates ko, die Fabric dann benachrichtigt ...)

Ich bin sehr neu zu knockout, so dass alle Kommentare / Vorschläge willkommen wären.

    
John M 08.09.2016 09:03
quelle

Tags und Links