En muchos de los constructores de modelos de vista de elemento UI de Magento 2, la defaults
matriz tendrá una propiedad imports
o exports
.
return Collection.extend({
defaults: {
//...
imports: {
rows: '${ $.provider }:data.items'
},
return Insert.extend({
defaults: {
//...
exports: {
externalFiltersModifier: '${ $.externalProvider }:params.filters_modifier'
},
Mirando la fuente del uiElement
módulo,
#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');
},
Estas importaciones / exportaciones parecen tener algo que ver con "vincular" información entre objetos cuando se instancia un objeto. Sin embargo, no está claro cómo funciona esta vinculación (¿basado en uiRegistry?) O cuál es la sintaxis de las cadenas ${ $.provider }:data.items
. Está claro que estas cadenas usan literales de plantilla que se expanden en algo como
foo_bar:data.items
Pero el significado de esta cadena final sigue siendo misterioso.
¿Alguien sabe cómo funcionan las propiedades de importación / exportación de estos objetos?
magento2
uicomponent
requirejs
uielement
Alan Storm
fuente
fuente
Respuestas:
Estas propiedades permiten que los componentes se conecten para que puedan interactuar entre sí. El principio es algo simple: importar (tomar) un valor de otro componente o exportar (enviar) un valor a un componente diferente o hacer ambas cosas.
Nota: para mantener la claridad en esta respuesta, un "componente" es un objeto Javascript devuelto por RequireJS, tiene un nombre específico y se puede acceder por ese nombre a través de UIRegistry.
Además, todos los ejemplos a continuación estarían dentro de la
defaults: {}
propiedad del componente.Con el principio establecido, comencemos con lo que considero el concepto más fácil:
Importaciones
Esta propiedad toma un valor de otro componente y lo asigna a la propiedad especificada. En el siguiente ejemplo, declaramos una importación:
Cuando Magento inicialice este componente, intentará asignar el valor a la
message
propiedad. Esta propiedad estará disponible en contexto KnockoutJS. Sin embargo, como sabemos ,imports.message
primero evaluará el valor como una expresión literal de plantilla. En este caso, Magento analizará$.provider
y debería obtener un valor. Si bien eso podría ser cualquier cantidad de cosas, en este ejemplo y de acuerdo con muchos de los casos de uso principales de Magento, es el nombre de un componente que está en el registro de UI. Eso se analizará antes del siguiente paso.Como la
message
propiedad está en laimports
propiedad, se pasará alsetLinks()
método enuiElement.initLinks()
. ElsetLinks()
método está enMagento/Ui/view/base/web/js/lib/core/element/links.js
. Allí, recorre todas las propiedades (solomessage
aquí) en el objeto que se pasó (imports
en este caso). En esas propiedades, intentará transferir datos de un componente a otro.La
transfer()
función es el próximo lugar de interés. Aquí, en el registro se busca el componente que es el "propietario", en el caso de una importación. Este componente es el que actualmente "posee" o tiene los datos y sería el$.provider
del ejemplo anterior. Si se encuentra el componente, procederá a vincular los datos con lasetLink()
función.Hay dos cosas notables en ese método: primero, establece un detector de eventos en la propiedad, y segundo, transferirá inmediatamente los datos si se ha enviado el indicador correspondiente. En mis pruebas, siempre pasó el
immediate
parámetro, por lo que la transferencia ocurrió durante la inicialización. Sin embargo, debido al detector de eventos que se adjuntó en el primer paso, continuará actualizando los valores, si cambian, para que ambos componentes permanezcan sincronizados.Los datos se configuran en (o, en términos más simples: "devuelto al") componente que tenía la
imports: {}
propiedad. Como mencioné anteriormente, luego se asigna directamente a la propiedad del componente que lo declaró, esencialmentethis.message
en el ejemplo anterior y nothis.defaults.imports.message
. Como resultado,data-bind="text: message
debe mostrar el valor devuelto por ladata.message
propiedad del componente vinculado .Este enfoque le permite definir cuál es el nombre de la propiedad en el componente fuente. En el ejemplo anterior, podría usar en
alertMessage: ...
lugar demessage
como el nombre de propiedad de su componente.Exportaciones
Las exportaciones son lo contrario de
imports
. Se basan en la misma funcionalidad que las importaciones, pero en lugar de tomar datos de un componente y asignárselos a sí mismo, envía sus propios datos a otro componente. Como resultado, casi todo es lo contrario. Toma este ejemplo:En este ejemplo,
setLinks()
toma el valor de laphoneNumber
propiedad de este componente y lo asigna a laphone
propiedad del formulario de contacto . Es lo mismo que declarar explícitamente unaphone
propiedad en el$.contactForm
componente. Sin ninguna configuración particular en el$.contactForm
, puede acceder a estos datos directamente. Tal como esto en una plantilla Knockout:data-bind="text: phone
.Enlaces
Finalmente, la
links
propiedad es lo mismo que declarar ambasimports
yexports
para la misma propiedad. A primera vista, esto puede parecer una referencia circular. Si bien es así, en ocasiones, esto podría ser útil. Si bien estoy seguro de que hay muchos más casos de uso, el que puedo ver es la capacidad de un componente para manipular datos de otro componente dinámicamente. En este caso, ComponentA es la fuente de algunos datos y los muestra en la página. ComponentB necesita manipular esos datos y, por lo tanto,links
a esa propiedad. Puede mostrar los datos y manipular los datos reales en ComponentA sin extender o cambiar ComponentA.Sin embargo, una cosa a tener en cuenta es que, por defecto,
links
no son una forma de conectar otros dos módulos. En otras palabras, ComponentC no puedelink
ComponentA a ComponentB. Es un método de sincronización bidireccional de un componente con otro.La vinculación (
imports
,exports
ylinks
) casi siempre puede facilitar también las funciones asignadas a esas propiedades. Me encontré con un comportamiento extraño al crear observables y usar,links
pero en general funcionó bastante bien.El enlace proporciona valores que están disponibles en el alcance de KnockoutJS y pueden manipularse como lo haría con cualquier otra propiedad. Y, para reiterar claramente: recuerde que el
imports
,exports
ylinks
de objetos claves siempre se refieren a propiedades de la componente de corriente (aquel en el que esas propiedades fueron declaradas), mientras que pertenece el valor con el nombre y las propiedades del componente remoto .En conclusión, Magento utiliza esta funcionalidad de enlace para conectar diferentes componentes entre sí y es una forma de acceder, proporcionar o sincronizar datos con otros componentes.
fuente
imports
y enexports
lugar de hacerlolinks
. He encontradolinks
que es más oscuro y quebradizo. Si encontraste un ejemplo, ¿podrías compartir un enlace?