Essas propriedades permitem que os componentes sejam conectados para que eles possam interagir entre si. O princípio é um pouco simples: importar (obter) um valor de outro componente ou exportar (enviar) um valor para um componente diferente ou fazer as duas coisas.
Nota: para manter a clareza nesta resposta, um "componente" é um objeto Javascript retornado pelo RequireJS, tem um nome específico e pode ser acessado por esse nome através do UIRegistry.
Além disso, todos os exemplos abaixo estariam dentro da defaults: {}
propriedade do componente.
Com o princípio estabelecido, vamos começar com o que considero o conceito mais fácil:
Importações
Esta propriedade pega um valor de outro componente e o atribui à propriedade especificada. No exemplo a seguir, declaramos uma importação:
imports: {
message: '${ $.provider }:data.message'
}
Quando o Magento inicializa esse componente, ele tenta atribuir o valor à message
propriedade. Esta propriedade estará disponível no contexto KnockoutJS. Como sabemos , no entanto, ele avaliará o imports.message
valor como uma expressão literal do modelo primeiro. Nesse caso, o Magento analisará $.provider
e deve obter um valor. Embora possa haver várias coisas, neste exemplo e de acordo com muitos dos principais casos de uso do Magento, é o nome de um componente que está no registro da interface do usuário. Isso será analisado antes da próxima etapa.
Como a message
propriedade está na imports
propriedade, ela será passada para o setLinks()
método in uiElement.initLinks()
. O setLinks()
método é, em Magento/Ui/view/base/web/js/lib/core/element/links.js
. Lá, ele faz um loop sobre todas as propriedades (somente message
aqui) no objeto que foi passado ( imports
neste caso). Nessas propriedades, ele tentará transferir dados de um componente para outro.
A transfer()
função é o próximo local de interesse. Aqui, o registro é pesquisado para o componente que é o "proprietário", no caso de uma importação. Esse componente é o que atualmente "possui" ou possui os dados e seria $.provider
o exemplo acima. Se o componente for encontrado, ele continuará vinculando os dados à setLink()
função.
Há duas coisas a serem observadas nesse método: primeiro, ele define um ouvinte de evento na propriedade e, segundo, transfere imediatamente os dados se o sinalizador aplicável tiver sido enviado. Nos meus testes, sempre passava o immediate
parâmetro para que a transferência acontecesse durante a inicialização. No entanto, devido ao ouvinte de evento anexado na primeira etapa, ele continuará atualizando os valores, se eles forem alterados, para que os dois componentes permaneçam sincronizados.
Os dados são então configurados (ou, em termos mais simples: "retornados ao") componente que possuía a imports: {}
propriedade. Como mencionei anteriormente, ele é atribuído diretamente à propriedade do componente que o declarou - essencialmente this.message
no exemplo acima e não this.defaults.imports.message
. Como resultado, data-bind="text: message
deve exibir o valor retornado da data.message
propriedade do componente vinculado .
Essa abordagem permite definir qual é o nome da propriedade no componente de origem. No exemplo acima, você poderia usar em alertMessage: ...
vez de message
como o nome da propriedade do seu componente.
Exportações
As exportações são inversas imports
. Eles são baseados na mesma funcionalidade das importações, mas, em vez de pegar os dados de um componente e atribuí-los a si mesmo, ele envia seus próprios dados para outro componente. Como resultado, quase tudo é o oposto. Veja este exemplo:
exports: {
phoneNumber: '${ $.contactForm }:phone'
}
Neste exemplo, setLinks()
pega o valor da propriedade desse componentephoneNumber
e o atribui à phone
propriedade do formulário de contato . É o mesmo que declarar explicitamente uma phone
propriedade no $.contactForm
componente. Sem nenhuma configuração específica no $.contactForm
, você pode acessar esses dados diretamente. Talvez como este em um modelo Knockout: data-bind="text: phone
.
Ligações
Finalmente, a links
propriedade é a mesma que declarar ambas imports
e exports
para a mesma propriedade. À primeira vista, isso pode parecer uma referência circular. De certa forma, há momentos em que isso pode ser útil. Embora eu tenha certeza de que existem muitos outros casos de uso, o que posso ver é a capacidade de um componente manipular dados de outro componente dinamicamente. Nesse caso, o ComponentA é a fonte de alguns dados e os exibe na página. ComponentB precisa manipular esses dados e, portanto, links
para essa propriedade. Ele pode exibir os dados e manipular os dados reais no ComponentA sem nunca estender ou alterar o ComponentA.
Uma coisa a observar, porém, é que, por padrão, links
não é uma maneira de conectar outros dois módulos. Em outras palavras, o ComponentC não pode link
ComponentA para ComponentB. É um método de sincronizar bidirecionalmente um componente com outro.
Ligando ( imports
, exports
e links
) quase sempre pode facilitar as funções atribuídas a essas propriedades também. Eu tive algum comportamento estranho ao criar observáveis e usar, links
mas no geral funcionou muito bem.
A vinculação fornece valores que estão disponíveis no escopo KnockoutJS e podem ser manipulados como qualquer outra propriedade. E, para reiterar claramente: lembre-se que o imports
, exports
e links
do objeto chaves sempre se referem a propriedades do componente de corrente (aquele em que essas propriedades foram declaradas), enquanto que pertence o valor para o nome e as propriedades do componente remoto .
Em conclusão, o Magento usa essa funcionalidade de conexão para conectar componentes diferentes entre si e é uma maneira de acessar, fornecer ou sincronizar dados com outros componentes.