uiElementオブジェクトのインポート/エクスポートの「デフォルト」は何ですか?


8

Magento 2の多くのUI Elementビューモデルコンストラクターでは、defaults配列にimportsor exportsプロパティがあります。

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

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

uiElementモジュールのソースを見て、

#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');
    },

これらのインポート/エクスポートは、オブジェクトがインスタンス化されたときのオブジェクト間の「リンク」情報と関係があるようです。ただし、このリンクのしくみ(uiRegistryベース?)や、文字列の構文はどのようなものかは明確ではありません${ $.provider }:data.items。これらの文字列がテンプレートリテラルを使用することは明らかです。

foo_bar:data.items

しかし、この最後の文字列の意味はまだ神秘的です。

これらのオブジェクトのインポート/エクスポートプロパティの仕組みを知っている人はいますか?


私は実際にそれらを使用していないので、答えを投稿、しかしdevdocsはもう少し洞察与えることはありません:devdocs.magento.com/guides/v2.1/ui-components/...
Vinai

回答:


21

これらのプロパティを使用すると、コンポーネントを接続して、相互に作用させることができます。原理はやや単純です。別のコンポーネントから値をインポート(取得)するか、別のコンポーネントに値をエクスポート(送信)するか、その両方を行います。


注:この回答の明確さを維持するために、「コンポーネント」はRequireJSによって返されるJavaScriptオブジェクトであり、特定の名前があり、UIRegistryを介してその名前でアクセスできます。

さらに、以下のすべての例defaults: {}はコンポーネントのプロパティ内にあります。


原則が説明されたところで、私が最も簡単な概念と考えるものから始めましょう。

輸入

このプロパティは、別のコンポーネントから値を取得し、指定されたプロパティに割り当てます。次の例では、インポートを宣言しています。

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

Magentoがこのコンポーネントを初期化すると、messageプロパティに値を割り当てようとします。このプロパティはKnockoutJSコンテキストで使用できます。ただし、ご存じのとおりimports.message最初に値をテンプレートリテラル式として評価します。この場合、Magentoはを解析し$.provider、値を取得する必要があります。これはいくつでもかまいませんが、この例では、Magentoのコアユースケースの多くによれば、UIレジストリにあるコンポーネントの名前です。これは次のステップの前に解析されます。

以来messageプロパティがであるimports財産、それはに渡されますsetLinks()における方法uiElement.initLinks()setLinks()この方法はですMagento/Ui/view/base/web/js/lib/core/element/links.js。そこで、message渡されたオブジェクト(importsこの場合)のすべてのプロパティ(ここのみ)をループします。これらのプロパティでは、コンポーネント間でデータを転送しようとします。

transfer()関数は、関心の次の場所です。ここでは、インポートの場合、「所有者」であるコンポーネントがレジストリで検索されます。このコンポーネントは、現在「所有」しているか、データを持っているコンポーネント$.providerであり、上記の例ではになります。コンポーネントが見つかると、データとsetLink()関数をリンクします。

このメソッドには2つの注意点があります。1つはプロパティにイベントリスナーを設定すること、もう1つは、該当するフラグが送信された場合にデータをすぐに転送することです。私のテストでは、immediate初期化中に転送が行われるように、常にパラメーターを渡しました。ただし、最初のステップでアタッチされたイベントリスナーのため、値が変更された場合、値が更新され続け、両方のコンポーネントの同期が維持されます。

次に、そのimports: {}プロパティを持つコンポーネントにデータを設定します(簡単に言うと、「に戻る」)。私は先に述べたように、それはそれを宣言したコンポーネントのプロパティに直接割り当てられている-基本的にthis.message上記の例ではありませんthis.defaults.imports.message。その結果、data-bind="text: messageリンクされたコンポーネントのdata.messageプロパティから返された値が表示されます。

このアプローチでは、ソースコンポーネント内のプロパティ名を定義できます。上記の例alertMessage: ...messageは、コンポーネントのプロパティ名としての代わりにを使用できます。

輸出

エクスポートはの逆ですimports。これらはインポートと同じ機能に基づいていますが、1つのコンポーネントからデータを取得してそれ自体に割り当てるのではなく、独自のデータを別のコンポーネントに送信ます。その結果、ほとんどすべてが反対です。この例を見てみましょう:

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

この例でsetLinks()は、このコンポーネントのphoneNumberプロパティの値を取得して、連絡先フォームのphoneプロパティに割り当てます。これは、コンポーネントでphoneプロパティを明示的に宣言することと同じ$.contactFormです。で特別な設定をしなくても$.contactForm、このデータに直接アクセスできます。たぶん、Knockoutテンプレートでは次のようになりdata-bind="text: phoneます。

リンク集

最後に、このlinksプロパティは、同じプロパティに対して両方importsを宣言exportsするのと同じです。一見すると、これは循環参照のように見えるかもしれません。それはある意味ではありますが、これが役立つ場合があります。さらに多くのユースケースがあると確信していますが、私が見ることができるのは、あるコンポーネントが別のコンポーネントのデータを動的に操作する機能です。この場合、ComponentAは一部のデータのソースであり、ページに表示されます。ComponentBはそのデータを操作する必要があるためlinks、そのプロパティを使用します。ComponentAを拡張または変更することなく、ComponentAでデータを表示し、実際のデータを操作できます。

ただし、デフォルトでlinksは、他の2つのモジュールを接続する方法ではないことに注意してください。言い換えれば、ComponentCはlinkComponentAからComponentBへは移行できません。これは、あるコンポーネントを別のコンポーネントと双方向で同期する方法です。


(リンクimportsexportsおよびlinks)は、ほとんどの場合だけでなく、これらのプロパティに割り当てられた機能を容易にすることができます。オブザーバブルを作成して使用しているときに奇妙な動作に遭遇しましたlinksが、全体としては非常にうまくいきました。

リンクは、KnockoutJSスコープで使用可能な値を提供し、他のプロパティと同じように操作できます。そして、明確に繰り返すために:ことを覚えておいてくださいimportsexportsと、linksオブジェクトのキーを常にのプロパティを参照現在のコンポーネントの名前とプロパティに値が関係しながら、(これらのプロパティが宣言された1)リモート・コンポーネント


結論として、Magentoはこのリンク機能を使用して、さまざまなコンポーネントを相互に接続します。これは、他のコンポーネントとデータにアクセス、提供、または同期できる方法です。


素晴らしい説明@ bassplayer7-この例はありますか?私はそれがどのように機能するかを理解していますが、私の一生の間、2つの単純なUIコンポーネントでKOオブザーバブルを共有することはできません。
ベンクルック

@BenCrook、残念ながら、しばらくの間これで多くのことをしていないので、すぐに使えるものはありません。これであなたはそれを理解したと確信していますがimportsexportsではなくで作業することをお勧めしlinksます。私はlinksもっとあいまいで脆いことがわかりました。例を見つけた場合、リンクを共有できますか?
–bassplayer7

インポート/エクスポート/リンクを機能させようとしましたが失敗しました。Vinaiはここで質問に答えましたが、まだ試す機会がありませんでした。
ベン・クルック

この情報は、公式の開発者向けドキュメントで役立つでしょう。UI Cmponentプロセスは恐ろしい獣です。
Nathaniel Rogers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.