Consejos y ejemplos del uso de JS Knockout en Magento 2

¡Hola a los lectores del blog de Amasty! Hoy vamos a hablar sobre qué es JS Knockout , ejemplos de cómo usarlo en el comercio electrónico, por qué Magento 2 requiere la configuración de JS y las soluciones de frontend de Magento 2. Knockout (o KO) es una biblioteca de JavaScript que se usa ampliamente para crear la parte frontal de Magento 2, la  página de pago en particular.

¡Oye! ¿Quiere aumentar la tasa de conversión de pago en su tienda Magento 2? Pruebe el módulo One Step Checkout . ¡Habilite Google Auto Suggest, agregue la opción de fecha de entrega, personalice el diseño de la página de pago y aumente sus ventas!

Knockout implementa el patrón de diseño Model-View-View Model (MVVM) con plantillas y permite crear páginas dinámicas, que cambian con respecto a las acciones de un usuario. La introducción de esta biblioteca trajo cambios positivos significativos al desarrollo de Magento 2 e hizo posible crear una gama mucho más amplia de componentes de interfaz receptivos, como el selector de fechas, las ventanas emergentes y otros elementos de diseño personalizados. A pesar de los beneficios, implementar las soluciones de Magento 2 con Knockout JS y la traducción de Magento 2 JS es bastante complicado para muchos desarrolladores.

Entonces, en este tutorial, veremos cómo funciona JS Knockout y cómo usarlo en sus proyectos de Magento 2. Pero KO es solo una de las bibliotecas JS que usa Magento 2, hay muchas otras, por ejemplo, jQuery, Underscore, etc.

Resumen del artículo [ ocultar ]

  • Cómo funciona Knockout JS en Magento 2
  • Cómo funciona Knockout JS en los componentes de la interfaz de usuario de Magento 2
  • Lo bueno de Knockout es
  • Knockout observables en acción
  • Knockout para el intercambio de datos entre los componentes de la interfaz de usuario
  • Knockout y uso de un componente de interfaz de usuario en un diseño de página
  • Knockout y transferencia de datos del servidor al componente de la interfaz de usuario
  • Línea de fondo

Cómo funciona Knockout JS en Magento 2

Agregado con varios cambios a Magento 2, KO ahora se usa ampliamente para enlaces de variables, utilizando el atributo de enlace de datos, agregando controladores de eventos de JavaScript con la ayuda de enlaces personalizados y rastreándolos. La documentación de Magento 2 muestra en detalle cómo funciona la biblioteca para estos fines. En general, el uso de Knockout JS en Magento 2 se refiere a la creación de componentes enriquecidos de una interfaz de página que, con KO en su lugar, contribuyen mucho a la comodidad de la interfaz de usuario.

Cómo funciona Knockout JS con los componentes de la interfaz de usuario de Magento 2

Los componentes de la interfaz de usuario de Magento 2 se utilizan para mostrar elementos particulares de la interfaz de usuario, como tablas, botones, pestañas, cuadros de diálogo y más. Los componentes de la interfaz de usuario constan de una declaración XML que especifica sus ajustes de configuración y estructura interna, una clase de JavaScript y plantillas relacionadas que utilizan los enlaces Knockout.

Para ser más específicos, un componente de la interfaz de usuario implementa una parte del patrón de diseño de MVVM o, en algunos casos, lo amplía. Un modelo aquí son los datos almacenados de su aplicación, la vista es un documento HTML relevante que describe cómo se representa el componente y un modelo de vista es una representación de código puro de los datos y las operaciones en una interfaz de usuario.

Los archivos frontend js se ubican convencionalmente de la siguiente manera:

app/code/<espacio_de_nombres_de_tu_módulo>/<nombre_de_tu_módulo>/view/<área>/web/js/

Y el área puede ser frontend, adminhtml o base.

Y los archivos frontend relacionados con las plantillas de archivos de JavaScript generalmente se encuentran a continuación:

app/code/<your_module_namespace>/<your_module_name>/view/frontend/web/template/

Para hacerlo más vívido, considere el componente de pago como ejemplo.

Primero, accedemos al  modelo a través de module-checkout/view/frontend/web/js/model/quote.js  y vemos la siguiente representación de código:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. definir ( [
  2.   ‘ko’ ,
  3.   ‘guión bajo’ ,
  4.   ‘domReady!’
  5. ] , función ( ko , _ ) {
  6.   ‘uso estricto’ ;
  7.  
  8. /**
  9.  * Obtener datos de totales de los atributos de extensión.
  10.  * @param {*} datos
  11.  * @devoluciones {*}
  12.  */
  13. var procederTotalsData = función ( datos ) {
  14.         if ( _. isObject ( datos ) && _. isObject ( datos [ ‘extension_attributes’ ] ) ) {
  15.             _. cada ( datos [ ‘extension_attributes’ ] , función ( elemento , índice ) {
  16.                 datos [ índice ] = elemento ;
  17.             } ) ;
  18.         }
  19.  
  20.         devolver datos ;
  21.     } ,
  22.     dirección de facturación = ko. observable ( nulo ) ,
  23.     dirección de envío = ko. observable ( nulo ) ,
  24.     método de envío = ko. observable ( nulo ) ,
  25.     método de pago = ko. observable ( nulo ) ,
  26.     quoteData = ventana. checkoutConfig . citar datos ,
  27.     basePrecioFormat = ventana. checkoutConfig . formato de precio base ,
  28.     precioFormato = ventana. checkoutConfig . formato de precio ,
  29.     storeCode = ventana. checkoutConfig . código de tienda ,
  30.     totalsData = procederTotalsData ( ventana. checkoutConfig . totalsData ) ,
  31.     totales = ko. observable ( datos totales ) ,
  32.     totales recogidos = ko. observable ( { } ) ;
  33.  
  34. volver {
  35.     totales : totales ,
  36.     dirección de envío : dirección de envío ,
  37.     método de envío : método de envío ,
  38.     dirección de facturación : dirección de facturación ,
  39.     método de pago : método de pago ,
  40.     correo electrónico invitado : nulo ,
  41.  
  42.     /**
  43.      * @devolver {*}
  44.      */
  45.     getQuoteId : función ( ) {
  46.         devuelve quoteData [ ‘entity_id’ ] ;
  47.     } ,
  48.  
  49.     /**
  50.      * @return {booleano}
  51.      */
  52.     esVirtual : función ( ) {
  53.         regresa !! Número ( quotData [ ‘is_virtual’ ] ) ;
  54.     } ,
  55.  
  56.     /**
  57.      * @devolver {*}
  58.      */
  59.     obtenerFormatoPrecio : función ( ) {
  60.         formato de precio de retorno ;
  61.     } ,
  62.    
  63.     …

La ruta a la plantilla del componente se muestra en la  sección predeterminada  del componente y toma la forma de un objeto con la clave denominada  plantilla El modelo de vista contiene información sobre todas las funciones que se utilizarán en la parte de vista del componente. Además, el modelo de vista se usa para declarar variables observables .

En segundo lugar,  la vista  se encuentra en  module-checkout/view/frontend/web/template/review/actions/default.html  y tiene el siguiente aspecto:

La plantilla del componente contiene directivas Knockout especiales que se utilizan para vincular ViewModel con la plantilla.

Para obtener más información sobre las directivas y el enlace de Knockout, consulte la  documentación oficial de Knockout .

Lo bueno de Knockout

Uno que use Knockout definitivamente apreciará los observables. Los observables son objetos JavaScript especiales que pueden notificar a los suscriptores sobre cambios y detectar dependencias automáticamente. Los observables obtuvieron su nombre porque se pueden observar, lo que significa que otro código puede suscribirse y reaccionar a sus cambios. De esta manera, los observables permiten crear una conexión dinámica entre las variables y los datos para actualizar los datos de la plantilla cuando cambian los datos de un componente.

Si bien los observables son perfectos para detectar y responder a los cambios de un objeto, trabajar con cambios en una colección de cosas requiere un observableArray . ObservableArray rastrea qué objetos están en la matriz, pero no su estado. En pocas palabras, observableArray notifica a los suscriptores cuando se agregan, eliminan, filtran, reorganizan, etc.

En general, los observables ayudan a los desarrolladores a crear lógica para diversos casos que requieren una reacción instantánea a los cambios de ciertos objetos.

Knockout observables en acción

Ahora, consideremos un ejemplo del uso de observables de eliminación de JS en Magento 2. Accedemos al modelo de vista a través de la ruta module-customer/view/frontend/web/js/view/authentication-popup.js  y declaramos la  variable isLoading  como observable usando una palabra clave relevante – observable.

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. definir ( [
  2.   ‘jquery’ ,
  3.   ‘ko’ ,
  4.   ‘Magento_Ui/js/formulario/formulario’ ,
  5.   ‘Cliente_Magento/js/acción/login’ ,
  6.   ‘Cliente_Magento/js/datos-del-cliente’ ,
  7.   ‘Magento_Customer/js/model/authentication-popup’ ,
  8.   ‘mago/traducir’ ,
  9.   ‘mago/url’ ,
  10.   ‘Magento_Ui/js/modal/alerta’ ,
  11.   ‘mago/validación’
  12. ] , función ( $ , ko , componente , acción de inicio de sesión , datos del cliente , ventana emergente de autenticación , $ t , url , alerta ) {
  13.   ‘uso estricto’ ;
  14.  
  15. componente de retorno . extender ( {
  16.     URL de registro : ventana. autenticación emergente . URLRegistrocliente ,
  17.     olvidastePasswordUrl : ventana. autenticación emergente . clientForgotPasswordUrl ,
  18.     autocompletar : ventana. autenticación emergente . autocompletar ,
  19.     ventana modal : nulo ,
  20.     isLoading : ko. observable ( falso ) ,
  21.  
  22.     predeterminados : {
  23.         plantilla : ‘Magento_Customer/authentication-popup’
  24.     } ,
  25.    
  26.     …

Ahora, pasemos a la parte Ver que también contiene la  variable isLoading  . La ruta es:  module-customer/view/frontend/web/template/authentication-popup.html .

Finalmente, eche un vistazo a un ejemplo de suscripción a un evento:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. < div class = «autenticación de bloque»
  2.     data-bind = «afterRender: setModalElement, blockLoader: isLoading»
  3.     estilo = «pantalla: ninguno» >
  4.     < div class = «bloquear bloque-nuevo-cliente»
  5.         enlace de datos = «attr: {‘etiqueta de datos’: $t(‘o’)}» >
  6.         < div clase = «título-bloque» >
  7.             < strong id = «bloquear-nuevo-cliente-encabezado»
  8.                    rol = «encabezado»
  9.                    aria-nivel = «2»
  10.                    data-bind = «i18n: ‘Pagar como nuevo cliente'» >< / strong >
  11.         < / div >
  12.         < div class = «bloquear-contenido» aria-labelledby = «bloquear-nuevo-encabezado-cliente» >
  13.             < p data-bind = «i18n: ‘Crear una cuenta tiene muchos beneficios:'» >< / p >
  14.             < ul >
  15.                 < li data-bind = «i18n: ‘Ver pedido y estado de envío'» >< / li >
  16.                 < li data-bind = «i18n: ‘Rastrear historial de pedidos'» >< / li >
  17.                 < li data-bind = «i18n: ‘Salir más rápido'» >< / li >
  18.             < / ul >
  19.             < div clase = «barra de herramientas de acciones» >
  20.                 < div clase = «primario» >
  21.                     < una clase = «acción acción-registro primario» data-bind = «attr: {href: registerUrl}» >
  22.                         < span data-bind = «i18n: ‘Crear una cuenta'» >< / span >
  23.                     < / a >
  24.                 < / div >
  25.             < / div >
  26.         < / div >
  27.     < / div >
  28.  

Accedemos a  module-checkout/view/frontend/web/js/view/cart/totals.js  y vemos:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. definir ( [
  2.   ‘jquery’ ,
  3.   ‘uiComponent’ ,
  4.   ‘Magento_Checkout/js/modelo/totales’ ,
  5.   ‘Magento_Checkout/js/modelo/servicio de envío’
  6. ] , función ( $ , componente , totalsService , shippingService ) {
  7.   ‘uso estricto’ ;
  8.  
  9.   componente de retorno . extender ( {
  10.       isLoading : totalsService. está cargando ,
  11.  
  12.       /**
  13.       * @anular
  14.       */
  15.       inicializar : función ( ) {
  16.           este ._super ( ) ;
  17.           TotalsService. totales _ suscribirse ( función ( ) {
  18.               $ ( ventana ) . disparador ( ‘redimensionar’ ) ;
  19.           } ) ;
  20.           servicio de envío. obtenerTarifasEnvio ( ) . suscribirse ( función ( ) {
  21.               $ ( ventana ) . disparador ( ‘redimensionar’ ) ;
  22.           } ) ;
  23.       }
  24.   } ) ;
  25. } ) ;


En el código, puede ver que la suscripción se refiere a los 
Totales  observables. Ahora, cuando cambien los  Totales  , una función relacionada activará el evento  Redimensionar  .

Knockout para el intercambio de datos entre los componentes de la interfaz de usuario

En Magento 2, todas las variables definidas en un componente de UI están limitadas por el área de visibilidad de este componente. Sin embargo, los componentes aún pueden intercambiar datos y variables. Para ello, debe crear un modelo de datos especial en forma de un objeto JavaScript estándar y, utilizando la  directiva de definición  , incrustar este modelo de datos en el componente con el que desea intercambiar datos. Las funciones y variables de este modelo de datos también se pueden utilizar en el componente de destino.

Los objetos de JavaScript se transfieren por referencia. Entonces, si una variable observable que pertenece a un modelo de datos cambia, este cambio afectará el objeto de origen en el que se define esta variable. En pocas palabras, cuando los componentes comparten variables a través de un modelo de datos, cualquier actualización de una variable observable afectará a todos los componentes que usan esta variable y el modelo de datos compartido.

Aquí hay un ejemplo del modelo del módulo de pago al que accedemos a través de module-checkout/view/frontend/web/js/model/shipping-service.js :

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. definir ( [
  2.   ‘ko’ ,
  3.   ‘Magento_Checkout/js/model/checkout-data-resolver’
  4. ] , función ( ko , checkoutDataResolver ) {
  5.   ‘uso estricto’ ;
  6.  
  7.   var tarifas de envío = ko. Matriz observable ( [ ] ) ;
  8.  
  9.   volver {
  10.       isLoading : ko. observable ( falso ) ,
  11.  
  12.       /**
  13.       * Establecer tarifas de envío
  14.       *
  15.       * @param {*} rateData
  16.       */
  17.       setShippingRates : function ( ratesData ) {
  18.           tarifas de envío ( rateData ) ;
  19.           tarifas de envio. valorHaMutado ( ) ;
  20.           checkoutDataResolver. resolveShippingRates ( ratesData ) ;
  21.       } ,
  22.  
  23.       /**
  24.       * Obtener tarifas de envío
  25.       *
  26.       * @devoluciones {*}
  27.       */
  28.       obtenerTarifasEnvio : función ( ) {
  29.           tarifas de envío de devolución ;
  30.       }
  31.   } ;
  32. } ) ;


Preste atención al  método
setShippingRates  que afecta a una variable observable denominada  shippingRates Este método también se usa en el siguiente modelo  module-checkout/view/frontend/web/js/model/shipping-rate-processor/customer-address.js :

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. definir ( [
  2.   ‘Magento_Checkout/js/model/resource-url-manager’ ,
  3.   ‘Magento_Checkout/js/modelo/presupuesto’ ,
  4.   ‘mago/almacenamiento’ ,
  5.   ‘Magento_Checkout/js/modelo/servicio de envío’ ,
  6.   ‘Magento_Checkout/js/model/shipping-rate-registry’ ,
  7.   ‘Magento_Checkout/js/modelo/procesador de errores’
  8. ] , function ( resourceUrlManager , cotización , almacenamiento , servicio de envío , rateRegistry , errorProcessor ) {
  9.   ‘uso estricto’ ;
  10.  
  11.   volver {
  12.       /**
  13.       * @param {Objeto} dirección
  14.       */
  15.       getRates : función ( dirección ) {
  16.           var caché ;
  17.  
  18.           servicio de envío. estáCargando ( verdadero ) ;
  19.           caché = tasaRegistro. get ( dirección. getKey ( ) ) ;
  20.  
  21.           si ( caché ) {
  22.               servicio de envío. setShippingRates ( caché ) ;
  23.               servicio de envío. estáCargando ( falso ) ;
  24.           } más {
  25.               almacenamiento. publicar (
  26.                   resourceUrlManager. getUrlForEstimationShippingMethodsByAddressId ( ) ,
  27.                   JSON. cadena ( {
  28.                       identificador de dirección : dirección. ID de la dirección del cliente
  29.                   } ) ,
  30.                   falso
  31.               ) . hecho ( función ( resultado ) {
  32.                   tasaRegistro. set ( dirección. getKey ( ) , resultado ) ;
  33.                   servicio de envío. setShippingRates ( resultado ) ;
  34.               } ) . fail ( función ( respuesta ) {
  35.                   servicio de envío. establecer Tarifas de Envío ( [ ] ) ;
  36.                   errorProcesador. proceso ( respuesta ) ;
  37.               } ) . siempre ( función ( ) {
  38.                   servicio de envío. estáCargando ( falso ) ;
  39.               }
  40.               ) ;
  41.           }
  42.       }
  43.   } ;
  44. } ) ;


En este modelo, aplicamos dependencias para transferir el  modelo
shippingService  al modelo  customerAddress  y usamos el método  setShippingService  del  modelo shippingService  . Además, se actualiza la variable observable  isLoading  . De esta forma, conectamos el   modelo de  dirección de cliente con el modelo de servicio de envío  y habilitamos el intercambio de datos entre los dos.

Knockout y uso de un componente de interfaz de usuario en un diseño de página

Ahora, veamos un ejemplo de implementación de un componente de interfaz de usuario en un archivo de diseño. Después de acceder al archivo XML ubicado en  Amasty/Extrafee/view/frontend/layout/checkout_cart_index.xml , obtenemos:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. < nombre del contenedor de referencia = «carrito.resumen» >
  2.             <block ifconfig = «amasty_extrafee/frontend/cart» class = «AmastyExtrafeeBlockCartFeeOptions» name = «amasty.extrafee.options» template = «Amasty_Extrafee::cart/fee/options.phtml» antes = «pago.carrito.envío» >
  3.                 <argumentos >
  4.                     < nombre del argumento = «jsLayout» xsi:tipo = «matriz» >
  5.                         < nombre del elemento = «componentes» xsi:tipo = «matriz» >
  6.                             < nombre del artículo = «block-amasty-extrafee-summary» xsi:type = «array» >
  7.                                 < nombre del elemento = «componente» xsi:tipo = «cadena» > uiComponent </elemento >
  8.                                 < nombre del elemento = «hijos» xsi:tipo = «matriz» >
  9.                                     < nombre del artículo = «block-amasty-extrafee» xsi:type = «array» >
  10.                                         < nombre del elemento = «componente» xsi:tipo = «cadena» > Amasty_Extrafee/js/view/summary/block </elemento >
  11.                                         < nombre del elemento = «ordenar» xsi:tipo = «cadena» > 5 </elemento >
  12.                                         < nombre del elemento = «config» xsi:type = «matriz» >
  13.                                             <item name = «template» xsi:type = «string» > Amasty_Extrafee/cart/block </item >
  14.                                             <item name = «blockType» xsi:type = «string» > Carrito </item >
  15.                                             < nombre del elemento = «deps» xsi:tipo = «matriz» >
  16.                                                 <item name = «0» xsi:type = «string» > block-amasty-extrafee-summary.block-amasty-extrafee.amasty-extrafee-fieldsets </item >
  17.                                             </elemento >
  18.                                         </elemento >
  19.                                         < nombre del elemento = «hijos» xsi:tipo = «matriz» >
  20.                                             < nombre del elemento = «amasty-extrafee-fieldsets» xsi:type = «array» >
  21.                                                 < nombre del elemento = «componente» xsi:tipo = «cadena» > Amasty_Extrafee/js/view/summary/fieldset </elemento >
  22.                                                 <item name = «displayArea» xsi:type = «string» > amasty-extrafee-fieldsets </item >
  23.                                                 < nombre del elemento = «config» xsi:type = «matriz» >
  24.                                                     <item name = «blockType» xsi:type = «string» > Pagar </item >
  25.                                                 </elemento >
  26.                                                 < nombre del elemento = «hijos» xsi:tipo = «matriz» > </elemento >
  27.                                             </elemento >
  28.                                         </elemento >
  29.                                     </elemento >
  30.                                 </elemento >
  31.                             </elemento >
  32.                         </elemento >
  33.                     </argumento >
  34.                 </argumentos >
  35.             </bloque >
  36.         </contenedor de referencia >


En la sección de componentes, establecemos la ruta al archivo Componente responsable del código Knockout del componente.
La plantilla de Vista se puede especificar en el código Knockout o en la sección de configuración del diseño de la página (es decir,
checkout_cart_index  en nuestro caso).

Así es como se ve en el ejemplo anterior:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. < nombre del elemento = «config» xsi: tipo = «matriz» >
  2.   < nombre del artículo = «plantilla» xsi: tipo = «cadena» > Amasty_Extrafee/cart/block < / artículo>
  3.   <item name = «blockType» xsi: type = «string» > Carrito < / item>
  4.   < nombre del elemento = «deps» xsi: tipo = «matriz» >
  5.     <item name = «0» xsi: type = «string» > block-amasty-extrafee-summary.block-amasty-extrafee.amasty-extrafee-fieldsets < / item>
  6.   < / elemento>
  7. < / elemento>


A continuación puede ver fragmentos del código del componente Bloque en el
Módulo de tarifa adicional ( Amasty_Extrafee/js/view/summary/block) .

En el Componente Amasty_Extrafee/js/view/summary/block , vemos:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. componente de retorno . extender ( {
  2.     isLoading : feeService. está cargando ,
  3.     predeterminados : {
  4.         plantilla : ‘Amasty_Extrafee/tarifa/bloque’ ,
  5.         módulos : {
  6.             conjunto de campos : ‘${ $.nombre }.amasty-extrafee-fieldsets’
  7.         }
  8.     } ,

Y la Vista ubicada en Amasty/Extrafee/view/frontend/web/template/fee/block.html se ve así:

div.embedPastebin { text-align:left; padding: 0; color: #000; margin: 0; font-family: monospace; background: #F7F7F7; border: 1px solid ddd; border-radius:3px; } div.embedPastebin { } div.embedPastebin div.embedFooter { background: #F7F7F7; color: #333; font-size: 100%; padding: 6px 12px; border-bottom: 1px solid #ddd; text-transform:uppercase; } div.embedPastebin div.embedFooter a, div.embedPastebin div.embedFooter a:visited { color: #336699; text-decoration:none; } div.embedPastebin div.embedFooter a:hover { color: red; } .noLines ol { list-style-type: none; padding-left: 0.5em; } .embedPastebin{background-color:#F8F8F8;border:1px solid #ddd;font-size:12px;overflow:auto;margin: 0 0 0 0;padding:0 0 0 0;line-height:21px} .embedPastebin div { line-height:21px; font-family:Consolas, Menlo, Monaco, Lucida Console,’Bitstream Vera Sans Mono’,’Courier’,monospace; } ol { margin:0; padding: 0 0 0 55px} ol li { border:0; margin:0;padding:0; } li.ln-xtra .de1, li.ln-xtra .de2 {background:#F8F8CE;} .embedPastebin ol li.li1 { margin: 0; } .embedPastebin ol li.li2 { margin: 0; }

Datos alojados con ♥ por Pastebin.comDescargar RawVer original
  1. < método de formulario = «publicar»
  2.      class = «amexfee-formulario-contenedor»
  3.      id = «amexfee-formulario»
  4.      visible = «visible()»
  5.      data-bind = «blockLoader: isLoading» >
  6.     < fieldset class = «fieldset amexfee-fieldset» each = «getRegion(‘amasty-extrafee-fieldsets’)» render = «» >< / fieldset >
  7. < / formulario >

Knockout y transferencia de datos del servidor al componente de la interfaz de usuario

Algunas páginas de Magento 2 incluyen un LayoutProcessor  responsable de la generación de componentes. Para transmitir variables dinámicas a la interfaz, debe crear la clase LayoutProcessor  en una carpeta de módulo separada , por ejemplo, denominada Block .

La  clase LayoutProcessor implementa  Magento/Checkout/Block/Checkout/LayoutProcessorInterface .

Luego, en la clase  LayoutProcessor  , implementamos el método Process  que acepta la entrada de una  variable jsLayout . jsLayout  es más bien una variable de matriz que solo una variable, ya que contiene información sobre todos los componentes que pertenecen a esta página.

Usando esta variable de matriz, podemos referirnos a nuestro componente y cambiar/agregar cualquier variable que necesitemos usar en la interfaz del componente.

Verifique este ejemplo de realización del  método  Process  en Amasty/Extrafee/Block/Cart/LayoutProcessor.php :

 

Línea de fondo

Hoy, analizamos cómo funciona Knockout JS en Magento 2. En particular, aprendimos a usar los elementos observables de Knockout en los componentes de la interfaz de usuario, agregar componentes de la interfaz de usuario a un diseño de página, habilitar el intercambio de datos entre los componentes de la interfaz de usuario y permitir la transferencia de datos de un servidor a la frontend de un componente.

Espero que este artículo te haya ayudado a comprender mejor Knockout y esperamos tus comentarios e ideas en el feed a continuación.

PD Un agradecimiento especial a Oleg Ivanov por la ayuda con esta publicación.