o que significa "displayArea" e "provider" do checkout_index_index.xml no magento2


Respostas:


22

Para entender o que checkoutProvidere displayAreasão, você deve primeiro entender o alcance que você está procurando em: jsLayout.

jsLayouté um monte de configuração do JavaScript para os elementos da interface do usuário do JavaScript na página de checkout. Se você olhar module-checkout/view/frontend/templates/onepage.phtml, notará os seguintes x-magento-initdados:

<script type="text/x-magento-init">
    {
        "#checkout": {
            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
        }
    }
</script>

Isso é onde tudo começa. Afirma:

Para o elemento #checkout, inicialize o Magento_Ui/js/core/appcomponente com as seguintes informações: ...

E a informação que recebe é a informação criado no XML de layout: jsLayout. Agora, isso significa que tudo em seu XML agora é passado para o Magento_Ui/js/core/appcomponente (deixando plug-ins e processadores de layout e outras coisas fora da equação no momento ...)

Agora, não vou me aprofundar nos detalhes de como module-ui/view/base/web/js/core/app.jstudo se resume, porque isso tornaria este post muito, muito longo, mas o resumo é este:

  • O Magento_Ui/js/core/appcomponente cria um checkoutcomponente.
  • Este será um componente do tipo uiComponent(este é um componente muito genérico que pode ser usado para adiar seus próprios componentes de interface do usuário personalizados. Ele vem com renderização básica de modelo de knockout e outras coisas).
  • Será o modelo para nós Magento_Checkout/web/frontend/template/onepage.html.
  • Ele vai criar vários filhos (com o nome errors, estimation, steps, etc ...)
  • A stepscriança também será a uiComponent.
  • Este ciclo continua ... a configuração cria filhos com vários parâmetros.

Agora, para chegar à sua displayAreae provider-question: Como você viu acima, tudo é mapeado para as classes JavaScrip. A primeira vez que vemos o uso de displayAreaé quando nós criamos o steps-component, que é do tipo uiComponent. Então, uiComponentseria um candidato lógico para procurar o uso de displayArea.

Agora, a uiComponenté uma classe JavaScript do tipo Magento_Ui/js/lib/core/collection. (Você pode procurar isso em module-ui/view/base/requirejs-config.js). Isso mapeia para module-ui/view/base/web/js/lib/core/collection.js. Aqui vemos o seguinte uso:

/**
 * Synchronizes multiple elements arrays with a core '_elems' container.
 * Performs elemets grouping by theirs 'displayArea' property.
 * @private
 *
 * @returns {Collection} Chainable.
 */
_updateCollection: function () {
    var _elems = compact(this._elems),
        grouped;

    grouped = _elems.filter(function (elem) {
        return elem.displayArea && _.isString(elem.displayArea);
    });
    grouped = _.groupBy(grouped, 'displayArea');

    _.each(grouped, this.updateRegion, this);

    this.elems(_elems);

    return this;
},

Portanto, o que isso faz é "mapear" um uiComponent para um determinado grupo de componentes da interface do usuário. É importante saber, porque isso nos permite mover os componentes da interface do usuário para outros locais no layout, apenas manipulando o layout XML, assim como você faria com phtmlmodelos que são renderizados no servidor. Basta substituir o displayAreae você pode renderizar qualquer componente da interface do usuário JavaScript em qualquer outro lugar (considerando que a área de destino também é renderizada em algum lugar).

Agora, para a sua segunda pergunta: provider. Assim como procuramos displayArea, devemos começar a olhar primeiro para o componente da interface do usuário Magento_Checkout/js/view/form/element/email. E se olharmos para o requirejs-config.js, finalmente encontramos module-checkout/view/frontend/web/js/view/form/element/email.js.

Mas ... não provideré usado nesta classe. Então, vamos ver se conseguimos encontrar algo na classe que se estenda: Component(que é nossa uiComponentclasse-novamente).

Mas ... não providertambém. Bem, uiComponentsimplesmente se estende Element(que está localizado em module-ui/view/base/web/js/lib/core/element/element.js), então vamos dar uma olhada lá:

/**
 * Parses 'modules' object and creates
 * async wrappers for specified components.
 *
 * @returns {Element} Chainable.
 */
initModules: function () {
    _.each(this.modules, function (name, property) {
        if (name) {
            this[property] = this.requestModule(name);
        }
    }, this);

    if (!_.isFunction(this.source)) {
        this.source = registry.get(this.provider);
    }

    return this;
},

Bingo! Acontece que o provedor é usado como uma fonte para buscar dados. Se olharmos para o construtor de Element, você verá que, por padrão, está definido como vazio:

provider: '',

Então, de volta à nossa configuração. Se agora lermos nossa configuração, entenderemos que o item shippingAddressé um componente Magento_Checkout/js/view/shipping, que busca seus dados no checkoutProvider.

Então, isso nos deixa com duas perguntas:

  1. Onde é checkoutProviderdefinido?
  2. Como é usado no JavaScript de envio?

Bem, se você rolar até o final checkout_index_index.xml, notará que não passa de uma baunilha uiComponent:

<item name="checkoutProvider" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
</item>

E se você olhar module-checkout/view/frontend/web/js/view/shipping.js, verá que é usado assim:

registry.async('checkoutProvider')(function (checkoutProvider) {
    var shippingAddressData = checkoutData.getShippingAddressFromData();

    if (shippingAddressData) {
        checkoutProvider.set(
            'shippingAddress',
            $.extend({}, checkoutProvider.get('shippingAddress'), shippingAddressData)
        );
    }
    checkoutProvider.on('shippingAddress', function (shippingAddressData) {
        checkoutData.setShippingAddressFromData(shippingAddressData);
    });
});

Para ser honesto: é aqui que a minha análise para, porque também me torna difícil pesquisar e investir o que está acontecendo, mas espero que alguém possa buscá-lo daqui ...

Eu sei que tem algo a ver com o registry.async()retorno de um método que é executado imediatamente com uma função de retorno de chamada como argumento, mas alguém precisa explicar isso ...


* Aviso: Por todos os meios, por favor, corrija-me se eu estiver errado! Ainda não tentei nenhuma das opções acima, mas já trabalho há quase um ano com o Magento 2 e acredito que é assim que funciona. Infelizmente, não há muita documentação se você quiser mergulhar no fundo do oceano Magento.


2
então, o que é displayArea?
Marián Zeke Šedaj 28/11

1
Esta é uma análise brilhante, você já desenvolveu um entendimento adicional?
LM_Fielding

11

Seis meses após minha resposta original, acho que posso fornecer uma resposta melhor sobre o que displayAreaé.

No meu entendimento, tudo isso vem junto com o getTemplate()método dos Knockouts , o getRegion()método e os filhos nos componentes da interface do usuário. Um bom exemplo disso pode ser visto quando você está examinando vendor/magento/module-checkout/view/frontend/templates/registration.phtmle vendor/magento/module-checkout/view/frontend/web/template/registration.html.

Em registration.phtml, você verá um componente Magento UI padrão que tem filhos:

<script type="text/x-magento-init">
    {
        "#registration": {
            "Magento_Ui/js/core/app": {
               "components": {
                    "registration": {
                        "component": "Magento_Checkout/js/view/registration",
                        "config": {
                            "registrationUrl": "<?php /* @escapeNotVerified */ echo $block->getCreateAccountUrl(); ?>",
                            "email": "<?php /* @escapeNotVerified */ echo $block->getEmailAddress(); ?>"
                        },
                        "children": {
                            "errors": {
                                "component": "Magento_Ui/js/view/messages",
                                "sortOrder": 0,
                                "displayArea": "messages",
                                "config": {
                                    "autoHideTimeOut": -1
                                 }
                            }
                        }
                    }
                }
            }
        }
    }
</script>

Observe o uso de displayAreano children-node. Basicamente, ele informa ao Knockout que esse elemento filho deve ser renderizado em uma região chamada 'mensagens' .

Agora dê uma olhada no topo de registration.html:

<!-- ko foreach: getRegion('messages') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->

O que essa linha de código Knockout basicamente faz é: itera sobre todos os elementos filhos que estão presentes nas 'mensagens' displayArea e os renderiza.

Basicamente, o nome é um pouco confuso se você me perguntar. Por que você usaria 'displayArea' em um local e 'region' em outro local. Mas talvez minha suposição esteja totalmente incorreta. Talvez um desenvolvedor central do Magento possa esclarecer um pouco mais isso?


1
É isso que me confunde há tanto tempo que continuo vendo getRegione minha mente apenas implode. Obrigado por ambas as respostas, a propósito, muito útil!
Ben Crook

1
Bem, este é apenas meus 2 centavos. Espero que alguém dos principais desenvolvedores possa compartilhar alguma luz sobre esse tópico. Os internos mais profundos do Magento 2, e especialmente toda a implementação do Knockout / XHR, são algo que não está tão bem documentado.
Giel Berkers

2
Concordo, a menos que você mergulhe em muitos dos arquivos principais, não há outra maneira senão essa troca de pilhas para saber o que diabos está acontecendo.
Ben Crook
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.