So teilen Sie Knockout JS-Observables zwischen UI-Komponenten


12

Ich verstehe, wie man Eigenschaften einer UI-Komponente verwendet imports: {}undexports: {} teilt, wie zum Beispiel:

defaults: {
    exports: {
        shouldShowMessage: '${$.component}'
    }
}

Welches gibt den Komponentennamen in den Exporten zurück.

Geben Sie hier die Bildbeschreibung ein

Aber wenn ich versuche, ein beobachtbares Knockout zu exportieren, ist es immer undefiniert:

defaults: {
    exports: {
        shouldShowMessage: '${$.shouldShowMessage}'
    }
}

...

setupKoBindings: function() {
    this.shouldShowMessage = ko.observable('Testing');
}

Geben Sie hier die Bildbeschreibung ein

Um dieses Problem zu umgehen, werde ich ein Speichermodell erstellen, wie hier erläutert , aber ich würde es vorziehen, die Importe und Exporte zu verwenden.

Antworten:


12

Die Werte des Exportobjekts müssen in einen Namen und eine Eigenschaft einer UiComponent-Instanz aufgelöst werden, die beispielsweise durch ein ':' getrennt sind checkout.cart.total:title.
Der Exportzielname muss die UI-Komponente "Namespace" enthalten.

In Ihrem Beispiel setzen Sie den Wert auf eine Zeichenfolge, die in eine Eigenschaft der UiComponent aufgelöst wird, die die Exportquelle darstellt. Der Export ist undefiniert, wenn Sie ihn überprüfen, da dies kein gültiges Exportziel ist.

Hier ist ein Beispiel, das funktioniert:

defaults: {
    exportTarget: "foo.bar",
    exportTargetProperty: "showMessage",

    tracks: {
        shouldShowMessage: true
    },

    exports: {
        shouldShowMessage: '${$.exportTarget}:${$.exportTargetProperty}'
    }
}
...

Mit dem obigen Befehl wird der Wert der shouldShowMessageEigenschaft showMessagebei foo.barjeder Änderung des Werts mit dem vollständigen Namen in die Eigenschaft einer UiComponent kopiert .
Beachten Sie, dass dadurch die Zieleigenschaft nicht automatisch auch als KO beobachtbar wird. Dies muss explizit deklariert werden, wenn Wertänderungen KO auslösen sollen, um DOM-Knoten, die auf diese Eigenschaft zugreifen, erneut zu rendern.

Übrigens macht das Hinzufügen shouldShowMessagezum tracksObjekt es zu einem automatisch beobachtbaren Ko-es5. Die Verwendung eines wörtlichen ko.observable()Werks funktioniert auch.

Im obigen Beispiel sind die exportTargetund exportTargetPropertyin der konfiguriert defaults. Sie können auch als Teil der UiComponent-Optionen im JSON angegeben werden, was normalerweise sinnvoller ist, da dort die UiComponent-Hierarchie einschließlich der UiComponent-Namen definiert wird.

Abschließend möchte ich darauf hinweisen, dass ich persönlich der Meinung bin, dass Ihre Lösung, bei der ein Wertobjekt verwendet wird, um den Wert an die andere UI-Komponente zu übergeben, besser ist als die Verwendung von Exporten oder Importen. Nach meiner Erfahrung ist das Beibehalten des gemeinsamen Status im DOM oder in UiComponents in allen außer den einfachsten Fällen ein Rezept für Spaghetti-OOP.


Hervorragende Erklärung, danke @Vinai! Ich werde es versuchen, wenn ich Zeit habe, und dies als akzeptiert markieren, wenn es funktioniert.
Ben Crook

Bei der Verwendung trackssind einige Probleme aufgetreten . Das manuelle Abonnieren von Observablen funktioniert this.shouldShowMessage.subscribe is not a functionbei Verwendung nicht mehr. this.shouldShowMessage.subscribe(function() { ... }); Es funktioniert einwandfrei, wenn Observables auf andere Weise festgelegt werden. Es fühlt sich an, als würde mir ein Schritt fehlen oder ich kann tracksnicht auf die gleiche Weise ein Observable erstellen.
Ben Crook

Sie haben Recht, die Eigenschaften sind keine regulären Ko-Observablen mehr, sondern nur ES5-Getter / Setter-Paare. Wenn Sie auf die ursprüngliche beobachtbare Funktion zugreifen möchten, können Sie ko ko.getObservable(this, 'shouldShowMessage').subscribe(function(newValue) { ...});einfügen und verwenden (das erste Argument ist das viewmodel ( this), das zweite den Namen der verfolgten Eigenschaft. Weitere Informationen hier: github.com/SteveSanderson/knockout-es5
Vinai

Ahh das macht Sinn, du bist der Beste <3
Ben Crook

1
Nachdem ich mit Importen und Exporten herumgespielt habe und immer noch versagt habe, stimme ich zu, dass dies Spaghetti-Code ist. Ich habe aufgegeben und bleibe bei manuellen Abonnements und einem Speichermodell.
Ben Crook
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.