Magento 2: `<each />`タグとは何ですか?


13

私が知る限り、Magentoのバックエンドでグリッドを表示すると、次の「XHRにロードされた」KnockoutJSテンプレートが物事のレンダリングを開始します

File: vendor/magento//module-ui/view/base/web/templates/collection.html
URL:  http://magento.example.xom/pub/static/adminhtml/Magento/backend/en_US/Magento_Ui/templates/collection.html
<each args="data: elems, as: 'element'">
    <render if="hasTemplate()"/>
</each>

しかし、私は<each/>タグと<render/>タグが何であるかについて少し損をしています。それらは、ストックKnockoutJSの一部ではありません(またはそうではないようです)。

componentsを介してKnockoutJSにカスタムタグを追加できることは知っていますが、KnockoutJSに名前が付けられたコンポーネントeachまたはrenderKnockoutJSに追加された明白な場所は見当たりません。

ですから、これらが私が知らない場所に登録されたコンポーネントなのか、MagentoがKnockoutJSに対して行ったカスタムタグなどを完全にカスタマイズしたものなのかはわかりません。

注:私はここで完全に暗闇ではありません<each/>-JSONでレンダリングされたすべての子UIコンポーネントを反復処理し、そのテンプレートをレンダリングします(そのテンプレートが存在する場合)。

私がまったく明らかにしていないのは、これらのタグの実装方法です。データがどのようにバインドされているかをデバッグできるように、それらが実装されている場所を確認し、他のタグがある場合にMagentoがこれらのタグを作成するために使用するメカニズムを理解します。

回答:


10

ラファエルがほのめかし、それはMagentoのは、XHR(すなわちアヤックス)要求を介してKnockoutJSテンプレートをダウンロードするとき、それはまた、カスタムタグや属性の数を探していることのルーチンを解析するいくつかのカスタムを介してそれらを渡すことが判明します

このカスタム解析は、Magento_Ui/js/lib/knockout/template/rendererRequireJSモジュールによって実行されます。このモジュールのソースコードは、検索する多くのデフォルトのタグと属性を設定します。このレンダラーに追加のタグと属性を追加する他のモジュールもあります。たとえば、次の

#File: vendor/magento/module-ui/view/base/web/js/lib/knockout/bindings/scope.js
renderer
    .addNode('scope')
    .addAttribute('scope', {
        name: 'ko-scope'
    });

解析可能な属性のリストに<scope/>タグとscope属性(<div scope="...">)を追加します。

であるように思えるの基本的な考え方は、ネイティブノックアウト「タグなし」のテンプレートブロックにこれらのタグと属性を変換することです。たとえば、次のMagento KnockoutJSテンプレート

<each args="data: elems, as: 'element'">
    <render if="hasTemplate()"/>
</each>

次のネイティブKnockoutJSコードに変換します

<!-- ko foreach: {data: elems, as: 'element'} -->
    <!-- ko if: hasTemplate() --><!-- ko template: getTemplate() --><!-- /ko --><!-- /ko -->
<!-- /ko -->

この翻訳の正確なルールはまだわかりません。コードMagento_Ui/js/lib/knockout/template/rendererは少し間接的で、タグごとに、属性ごとに変更できるようです。

Magento KnockoutJSテンプレートをダウンロードし、それをネイティブのKnockoutJSコードに変換できる次のコードスニペットを作成しました。

jQuery.get('http://magento-2-1-0.dev/static/adminhtml/Magento/backend/en_US/Magento_Ui/templates/collection.html', function(result){
    var renderer = requirejs('Magento_Ui/js/lib/knockout/template/renderer')
    var fragment = document.createDocumentFragment();
    $(fragment).append(result);

    //fragment is passed by reference, modified
    renderer.normalize(fragment);
    var string = new XMLSerializer().serializeToString(fragment);
    console.log(string);    
})

Magentoがこれを行う理由について-私の推測では、KnockoutJSのコメントテンプレートの何らかの構文の強調表示と読みやすさを望んでいますが、マロリー風の理由を除外することはありません。


2

両方のタグはの下app/code/Magento/Ui/view/base/web/js/lib/knockout/template/renderer.jsに実装されていますが、どのように実装されているかを正確に理解するのはあまりよくありません。

_.extend(preset.nodes, {
    foreach: {
        name: 'each'
    },

    /**
     * Custom 'render' node handler function.
     * Replaces node with knockout's 'ko template:' comment tag.
     *
     * @param {HTMLElement} node - Element to be processed.
     * @param {String} data - Data specified in 'args' attribute of a node.
     */
    render: function (node, data) {
        data = data || 'getTemplate()';
        data = renderer.wrapArgs(data);

        renderer.wrapNode(node, 'template', data);
        $(node).replaceWith(node.childNodes);
    }
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.