Wofür sind die Standardeinstellungen für Import / Export in einem uiElement-Objekt?

8

In vielen Modellkonstruktoren der UI-Elementansicht von Magento 2 verfügt das defaultsArray über eine importsoder exports-Eigenschaft.

return Collection.extend({
    defaults: {
        //...
        imports: {
            rows: '${ $.provider }:data.items'
        },

return Insert.extend({
    defaults: {
        //...
        exports: {
            externalFiltersModifier: '${ $.externalProvider }:params.filters_modifier'
        },

Betrachtet man die Quelle des uiElementModuls,

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
    initLinks: function () {
        return this.setListeners(this.listens)
                   .setLinks(this.links, 'imports')
                   .setLinks(this.links, 'exports')
                   .setLinks(this.exports, 'exports')
                   .setLinks(this.imports, 'imports');
    },

Diese Importe / Exporte scheinen etwas mit dem "Verknüpfen" von Informationen zwischen Objekten zu tun zu haben, wenn ein Objekt instanziiert wird. Es ist jedoch nicht klar, wie diese Verknüpfung funktioniert (uiRegistry-basiert?) Oder wie die Syntax für Zeichenfolgen lautet ${ $.provider }:data.items. Es ist klar, dass diese Zeichenfolgen Vorlagenliterale verwenden, die sich zu so etwas wie erweitern

foo_bar:data.items

Aber die Bedeutung dieser letzten Saite ist immer noch rätselhaft.

Weiß jemand, wie die Import / Export-Eigenschaften dieser Objekte funktionieren?

Alan Storm
quelle
Ich werde keine Antwort posten, da ich sie nicht wirklich verwendet habe, aber die Devdocs geben ein wenig mehr Einblick: devdocs.magento.com/guides/v2.1/ui-components/…
Vinai

Antworten:

21

Mit diesen Eigenschaften können Komponenten verbunden werden, damit sie miteinander interagieren können. Das Prinzip ist etwas einfach: Importieren (Nehmen) eines Werts von einer anderen Komponente oder Exportieren (Senden) eines Werts an eine andere Komponente oder beides.


Hinweis: Um die Übersichtlichkeit dieser Antwort zu gewährleisten, ist eine "Komponente" ein Javascript-Objekt, das von RequireJS zurückgegeben wird, einen bestimmten Namen hat und über die UIRegistry unter diesem Namen aufgerufen werden kann.

Darüber hinaus befinden sich alle folgenden Beispiele in der defaults: {}Eigenschaft der Komponente.


Beginnen wir mit dem dargelegten Prinzip mit dem, was ich für das einfachste Konzept halte:

Importe

Diese Eigenschaft nimmt einen Wert von einer anderen Komponente und weist ihn der angegebenen Eigenschaft zu. Im folgenden Beispiel deklarieren wir einen Import:

imports: {
    message: '${ $.provider }:data.message'
}

Wenn Magento diese Komponente initialisiert, wird versucht, den Wert der messageEigenschaft zuzuweisen . Diese Eigenschaft wird im KnockoutJS-Kontext verfügbar sein. Wie wir jedoch wissen , wird der imports.messageWert zuerst als Vorlagenliteralausdruck ausgewertet . In diesem Fall analysiert Magento das $.providerund sollte einen Wert erhalten. Während dies eine beliebige Anzahl von Dingen sein kann, ist dies in diesem Beispiel und gemäß vielen der wichtigsten Anwendungsfälle von Magento der Name einer Komponente, die sich in der UI-Registrierung befindet. Das wird vor dem nächsten Schritt analysiert.

Da sich die messageEigenschaft in der importsEigenschaft befindet, wird sie an die setLinks()Methode in übergeben uiElement.initLinks(). Die setLinks()Methode ist in Magento/Ui/view/base/web/js/lib/core/element/links.js. Dort werden alle Eigenschaften (nur messagehier) des übergebenen Objekts ( importsin diesem Fall) durchlaufen. In diesen Eigenschaften wird versucht, Daten von einer Komponente zur anderen zu übertragen.

Die transfer()Funktion ist der nächste Ort von Interesse. Hier wird die Registrierung nach der Komponente durchsucht, die im Falle eines Imports der "Eigentümer" ist. Diese Komponente ist diejenige, die derzeit die Daten "besitzt" oder besitzt und die $.providerim obigen Beispiel wäre. Wenn die Komponente gefunden wird, werden die Daten mit der setLink()Funktion verknüpft .

Bei dieser Methode sind zwei Dinge zu beachten: Erstens wird ein Ereignis-Listener für die Eigenschaft festgelegt, und zweitens werden die Daten sofort übertragen, wenn das entsprechende Flag gesendet wurde. Bei meinen Tests wurde der immediateParameter immer übergeben , sodass die Übertragung während der Initialisierung erfolgte. Aufgrund des im ersten Schritt angehängten Ereignis-Listeners werden die Werte jedoch weiterhin aktualisiert, wenn sie sich ändern, sodass beide Komponenten synchron bleiben.

Die Daten werden dann auf die Komponente gesetzt (oder einfacher ausgedrückt: "an die" zurückgegeben "), die die imports: {}Eigenschaft hatte. Wie bereits erwähnt, wird es dann direkt der Eigenschaft der Komponente zugewiesen, die es deklariert hat - im Wesentlichen this.messageim obigen Beispiel und nicht this.defaults.imports.message. Infolgedessen data-bind="text: messagesollte der von der data.messageEigenschaft der verknüpften Komponente zurückgegebene Wert angezeigt werden .

Mit diesem Ansatz können Sie definieren, wie der Eigenschaftsname in der Quellkomponente lautet. Im obigen Beispiel können Sie alertMessage: ...statt messageals Eigenschaftsname Ihrer Komponente verwenden.

Exporte

Exporte sind die Umkehrung von imports. Sie basieren auf der gleichen Funktionalität wie Importe, aber anstatt Daten von einer Komponente zu übernehmen und sich selbst zuzuweisen, sendet sie ihre eigenen Daten an eine andere Komponente. Infolgedessen ist fast alles das Gegenteil. Nehmen Sie dieses Beispiel:

exports: {
    phoneNumber: '${ $.contactForm }:phone'
}

In diesem Beispiel wird setLinks()der Wert der Eigenschaft dieser Komponente verwendet und der phoneNumberEigenschaft des Kontaktformulars phonezugewiesen. Dies entspricht der expliziten Deklaration einer phoneEigenschaft in der $.contactFormKomponente. Ohne eine bestimmte Einrichtung in der $.contactFormkönnen Sie dann direkt auf diese Daten zugreifen. Vielleicht so in einer Knockout-Vorlage : data-bind="text: phone.

Links

Schließlich ist die linksEigenschaft dieselbe wie die Deklaration beider importsund exportsfür dieselbe Eigenschaft. Auf den ersten Blick mag dies wie ein Zirkelverweis erscheinen. In gewisser Weise kann dies hilfreich sein. Ich bin mir zwar sicher, dass es noch viele weitere Anwendungsfälle gibt, aber ich kann sehen, dass eine Komponente Daten von einer anderen Komponente dynamisch bearbeiten kann. In diesem Fall ist ComponentA die Quelle einiger Daten und zeigt diese auf der Seite an. ComponentB muss diese Daten und damit diese linksEigenschaft bearbeiten. Es kann sowohl die Daten anzeigen als auch die tatsächlichen Daten in ComponentA bearbeiten, ohne ComponentA jemals zu erweitern oder zu ändern.

Zu beachten ist jedoch, dass standardmäßig linkskeine Möglichkeit besteht, zwei andere Module miteinander zu verbinden. Mit anderen Worten, ComponentC kann linkComponentA nicht zu ComponentB. Es ist eine Methode zum bidirektionalen Synchronisieren einer Komponente mit einer anderen.


Die Verknüpfung ( imports, exportsund links) können erleichtern fast immer Funktionen als auch auf jene Eigenschaften zugeordnet. Ich bin beim Erstellen und Verwenden von Observablen auf ein seltsames Verhalten gestoßen, linksaber insgesamt hat es ganz gut funktioniert.

Die Verknüpfung enthält Werte, die im KnockoutJS-Bereich verfügbar sind und wie jede andere Eigenschaft bearbeitet werden können. Und wiederholen klar: nicht vergessen , dass das imports, exportsund Objektschlüssellinks immer auf Eigenschaften des beziehen Stromkomponente (die, in der diese Eigenschaften erklärt wurden), während der Wert bezieht sich auf den Namen und die Eigenschaften der Remote - Komponente .


Zusammenfassend lässt sich sagen, dass Magento diese Verknüpfungsfunktion verwendet, um verschiedene Komponenten miteinander zu verbinden. Auf diese Weise können wir auf Daten zugreifen, diese bereitstellen oder mit anderen Komponenten synchronisieren.

Bassplayer7
quelle
Tolle Erklärung @ bassplayer7 - Hast du Beispiele dafür? Ich verstehe, wie es funktioniert, aber für mein Leben kann ich nicht zwei meiner einfachen UI-Komponenten dazu bringen, ein beobachtbares KO zu teilen.
Ben Crook
@ BenCrook, leider habe ich eine Weile nicht viel damit gemacht, also habe ich nicht gleich einen. Ich bin mir sicher, dass Sie es inzwischen herausgefunden haben, aber ich schlage vor, mit importsund exportsnicht zu arbeiten links. Ich habe festgestellt links, dass es dunkler und spröder ist. Wenn Sie auf ein Beispiel gestoßen sind, können Sie einen Link teilen?
Bassplayer7
Ich habe versucht und konnte Import / Export / Links nicht zum Laufen bringen. Vinai hat die Frage hier beantwortet , obwohl ich noch keine Gelegenheit hatte, sie auszuprobieren.
Ben Crook
Diese Informationen wären in den offiziellen Entwicklungsdokumenten großartig. Der UI Cmponent-Prozess ist nur ein gruseliges Tier.
Nathaniel Rogers