Una introducción completa a Backbone.Marionette (Parte 3)

 

 

 

  • SmashingConf UX y diseño, Amberes 2024

  • Índice
    1. Enlace de eventos
    2. Destruyendo una vista
    3. Actualización DOM
    4. Disparadores DOM
    5. Almacenamiento en caché de elementos DOM
    6. Conclusión
      1. Otras lecturas

    En esta tercera parte de la serie, Joseph Zimmerman analizará cómo Marionette ayuda a mejorar las vistas en Backbone. Marionette extiende la Viewclase base de Backbone para brindarnos más funcionalidad integrada y convertir todo el código común en configuración. Es posible que en este artículo se mencionen algunas cosas que se refieren a artículos anteriores, y esto es parte de una serie sobre Marionette, por lo que si deseas aprender sobre Marionette, debes leer la serie completa.

     

    Para ayudarle a aprovechar todo el potencial de Marionette, hemos preparado un libro electrónico completo lleno de ejemplos prácticos útiles que también está disponible en Smashing Library . —Ed.

    En esta serie sobre Backbone.Marionette, ya hemos hablado Applicationy Module. Esta vez, veremos cómo Marionette ayuda a mejorar las vistas en Backbone . Marionette extiende la Viewclase base de Backbone para brindarnos más funcionalidad integrada, eliminar la mayor parte del código repetitivo y convertir todo el código común en configuración.

    Le recomiendo encarecidamente que vuelva atrás y lea primero los artículos sobre Aplicación y Módulo , si aún no lo ha hecho. Es posible que en este artículo se mencionen algunas cosas que se refieren a artículos anteriores, y esto es parte de una serie sobre Marionette, por lo que si deseas aprender sobre Marionette, debes leer la serie completa.

    Enlace de eventos

    Hasta hace poco, las vistas de Backbone a menudo se manejaban mal, lo que provocaba un problema horrible conocido como "vistas zombis". El problema fue causado por las opiniones que escuchaban los eventos en el modelo, que en sí mismo es completamente inofensivo. El problema era que cuando las vistas ya no eran necesarias y eran "descartadas", nunca dejaban de escuchar los eventos en el modelo, lo que significa que el modelo todavía tenía una referencia a la vista, evitando que fuera recolectada como basura. Esto provocó que la cantidad de memoria utilizada por la aplicación creciera constantemente y la vista seguiría respondiendo a los eventos del modelo, aunque no representaría nada porque se eliminó del DOM.

     

    Muchas extensiones y complementos de Backbone, incluida Marionette, solucionaron este problema desde el principio. Sin embargo, no entraré en detalles sobre eso, porque los desarrolladores de Backbone remediaron este problema ellos mismos (¡finalmente!) en el recientemente lanzado Backbone 1.0 agregando los métodos listenToy a , de los cuales hereda la “clase” de Backbone . Desde entonces, los desarrolladores de Marionette han eliminado su propia implementación de esta característica, pero eso no significa que Marionette no nos ayude con otras cosas relacionadas con la vinculación de eventos.stopListeningEventsView

    Para simplificar la vinculación de eventos en los modelos y colecciones de la vista, Marionette nos brinda algunas propiedades para usar al extender las vistas de Marionette: modelEventsy collectionEvents. Simplemente pase un objeto donde las claves sean el nombre del evento que estamos escuchando en el modelo o colección, y la propiedad sea el nombre de la función a llamar cuando se active ese evento. Mire este sencillo ejemplo:

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view modelEvents: { 'change:attribute': 'attributeChanged render', 'destroy': 'modelDestroyed' }, render: function(){ … }, attributeChanged: function(){ … }, modelDestroyed: function(){ … }});

    Esto logra lo mismo que usar listenTo, excepto que requiere menos código. Aquí está el código equivalente usando listenTo.

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view initialize: function() { this.listenTo(this.model, 'change:attribute', this.attributeChanged); this.listenTo(this.model, 'change:attribute', this.render); this.listenTo(this.model, 'destroy', this.modelDestroyed); }, render: function(){ … }, attributeChanged: function(){ … }, modelDestroyed: function(){ … }});

    Hay un par de cosas clave a tener en cuenta. Primero, modelEventsse usa para escuchar el modelo de la vista y collectionEventsse usa para escuchar la colección de la vista ( this.modely this.collection, respectivamente). En segundo lugar, habrás notado que hay dos devoluciones de llamada para el change:attributeevento. Cuando especifica una cadena para las devoluciones de llamada, puede tener tantos nombres de funciones de devolución de llamada como desee, separados por espacios. Todas estas funciones se invocarán cuando se desencadene el evento. Cualquier nombre de función que especifique en la cadena debe ser un método de la vista.

    También hay formas alternativas de especificar modelEventsy collectionEvents. Primero, en lugar de usar una cadena para especificar los nombres de los métodos en la vista, puedes asignar funciones anónimas:

     

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view modelEvents: { 'change': function() { … } }});

    Probablemente esta no sea la mejor práctica, pero la opción existe si la necesita. Además, en lugar de simplemente asignar un objeto literal a modelEventso collectionEvents, puede asignar una función. La función deberá devolver un objeto que tenga los eventos y las devoluciones de llamada. Esto le permite crear la lista de eventos y devoluciones de llamadas de forma dinámica. No he podido pensar en ninguna situación en la que necesites determinar dinámicamente los enlaces de eventos, pero si lo necesitas, esto podría ser muy útil.

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view modelEvents: function() { return {'destroy': 'modelDestroyed'}; }, modelDestroyed: function(){ … }});

    La característica modelEventsy collectionEventssigue el patrón que Backbone y Marionette utilizan con la mayor frecuencia posible: relegar el código a una configuración simple. El propio Backbone hizo esto con el eventshash, lo que le permite configurar fácilmente detectores de eventos DOM. Marionette modelEventsy collectionEventsestán directamente inspirados en la eventsconfiguración original de Backbone. Verá que este concepto de configuración aparece mucho, especialmente en artículos posteriores, cuando entremos en ItemView, CollectionViewy CompositeView.

    Destruyendo una vista

    Como mencioné al comienzo de la sección anterior, a veces es necesario descartar o eliminar una vista porque se destruyó un modelo o porque necesitamos mostrar una vista diferente en su lugar. Con stopListening, tenemos el poder de limpiar todos esos enlaces de eventos. Pero ¿qué pasa con la destrucción del resto de la vista? Backbone tiene una removefunción que stopListeningnos llama y también elimina la vista del DOM.

    Generalmente, esto sería todo lo que necesita, pero Marionette va un paso más allá al agregar la closefunción. Cuando utilices las vistas de Marionette, querrás llamar closeen lugar de hacerlo removeporque limpiará todas las cosas que las vistas de Marionette configuran en segundo plano.

    Otro beneficio que ofrece el método de Marionette closees que desencadena algunos eventos. Al comenzar a cerrar la vista, se activará el before:closeevento y luego el closeevento cuando finalice. Además de los eventos, puede especificar métodos en la vista que se ejecutarán justo antes de que se activen estos eventos.

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view onBeforeClose: function() { // This will run just before the before:close event is fired }, onClose: function(){ // This will run just before the close event is fired }});

    Si desea ejecutar algún código antes de que la vista desaparezca por completo, puede usar los métodos onBeforeClosey onClosever para que se ejecute automáticamente sin necesidad de escuchar los eventos. Simplemente declare los métodos y Marionette se asegurará de que sean invocados. Por supuesto, otros objetos seguirán necesitando escuchar los eventos en la vista. Aviation Questions and Answers

     

    Actualización DOM

    Cuando hablamos Application, mencioné Regionun poco. No entraré mucho en esto aquí (una vez que todos los artículos sobre vistas estén terminados, entraré en más detalles), pero debes saber que a Regiones un objeto que maneja mostrar, ocultar o descartar vistas en una parte particular. del DOM. Mire el código siguiente para ver cómo representar una vista en un archivo Region.

    var view = new FooView(); // Assume FooView has already been definedregion.show(view); // Assume the region was already instantiated. Just use "show" to render the view.

    Cuando use show, representará la vista (todas las clases de vista que Marionette implementa y que se basan en esta Viewclase base también llamarán a la onRenderfunción si la ha definido y activarán un renderevento cuando renderse invoque), la adjuntará al DOM y luego muestra la vista, lo que simplemente significa que showse activa un evento para que los componentes sepan que la vista se representó a través de un archivo Region. Después de que una vista se haya renderizado y luego mostrado, si la vista se vuelve a renderizar, se activará una actualización del DOM.

    En realidad, esto no es cierto en este momento debido a un error, pero está en la lista de tareas pendientes de los desarrolladores. Actualmente, cuando se representa una vista, se establecerá una bandera que indica que se representó. Luego, cuando se muestre la vista, establecerá una bandera que indicará que se mostró. En el momento en que ambos indicadores se hayan activado, se activará una actualización del DOM. Luego, en cualquier momento posterior, la actualización del DOM se activará cada vez que se represente o muestre la vista. Tenga esto en cuenta si necesita utilizar esta funcionalidad.

    Cuando se activa una actualización de DOM, primero ejecutará el onDomRefreshmétodo de la vista (si definió uno) y luego activará el dom:refreshevento en la vista. Esto es especialmente útil para complementos de UI (como jQuery UI, Kendo UI, etc.) con algunos widgets que dependen del elemento DOM con el que están trabajando en el DOM real. A menudo, cuando se representa una vista, no se agregará al DOM hasta que finalice la representación. Esto significa que no puede utilizar el complemento durante rendero en su onRenderfunción.

    Sin embargo, puede usarlo en onShow(que se invoca justo antes de que showse active el evento) porque se supone que una Región debe estar adjunta a un nodo DOM existente (como veremos en un artículo futuro). Ahora, dado que se mostró la vista, sabrá que la vista está en el DOM; por lo tanto, cada vez que renderse llama, se realizará una actualización del DOM inmediatamente después del renderizado y podrá volver a llamar a la funcionalidad del complemento de interfaz de usuario de forma segura.

    Disparadores DOM

    A veces, cuando un usuario hace clic en un botón, desea responder al evento, pero no desea que la vista se encargue del trabajo. En su lugar, desea que la vista active un evento para que otros módulos que están escuchando este evento puedan responder a él. Supongamos que tiene un código similar a este:

     

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view events: { 'click .awesomeButton': 'buttonClicked' }, buttonClicked: function() { this.trigger('awesomeButton:clicked', this); }});

    La función para manejar el evento de clic simplemente activa un evento en la vista. Marionette tiene una función que le permite especificar un hash de estos eventos para simplificar este código. Al especificar la triggerspropiedad al extender a View, puede asignar un hash muy similar a la eventspropiedad; pero, en lugar de darle el nombre de uno de los métodos de la vista a invocar, le da el nombre de un evento a activar. Entonces, podemos convertir el fragmento anterior a esto:

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view triggers: { 'click .awesomeButton': ' awesomeButton:clicked ' }});

    Y hará casi lo mismo. Hay una diferencia importante entre estos dos fragmentos: los argumentos que se pasan a las funciones de escucha. En el primer fragmento, todo lo que pasamos a las funciones que escuchan el evento fue this, que era la vista. Usando triggers, Marionette pasará un solo objeto con tres propiedades como argumento para cada una de las funciones. Estas tres propiedades son las siguientes:

    • viewUna referencia al objeto de vista que desencadenó el evento.
    • modelUna referencia a la modelpropiedad de la vista, si la tiene.
    • collectionUna referencia a la collectionpropiedad de la vista, si la tiene.

    Entonces, si te suscribieras al evento del fragmento anterior, se vería así:

    // 'view' refers to an instance of the previously defined View typeview.on('awesomeButton:clicked', function(arg) { arg.view; // The view instance arg.model; // The view's model arg.collection; // The view's collection}

    Sé que no sobran casos de uso para esto, pero en las pocas situaciones en las que se aplica, puede ahorrar muchos problemas.

    Almacenamiento en caché de elementos DOM

    A menudo, this.$elno es el único elemento que necesitarás manipular directamente. En tales casos, mucha gente hará algo como esto:

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view render: function() { this.list = this.$('ul'); this.listItems = this.$('li'); . . . // Now we use them and use them in other methods, too. }});

    Una vez más, Marionette simplifica esto al convertir todo esto en una configuración simple. Simplemente especifique una uipropiedad que contenga un hash de nombres y sus selectores correspondientes:

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view ui: { list: 'ul', listItems: 'li' }});

    Puedes acceder a estos elementos con this.ui.x, donde xestá el nombre especificado en el hash, como por ejemplo this.ui.list. Esta uipropiedad se convierte en objetos jQuery almacenados en caché mediante el bindUIElementsmétodo. Si está ampliando Marionette.View, en lugar de uno de los otros tipos de vista que ofrece Marionette, deberá llamar a este método usted mismo; de lo contrario, los otros tipos de vista lo llamarán automáticamente.

    Backbone.Marionette.View.extend({ // We don't normally directly extend this view ui: { list: 'ul', listItems: 'li' }, render: function() { // render template or generate your HTML, then… this.bindUIElements(); // now you can manipulate the elements this.ui.list.hide(); this.ui.listItems.addClass('someCoolClass'); }});

    Conclusión

    Ya hemos visto una gran cantidad de características que Marionette aporta a las vistas que reducen la complejidad y la cantidad de código requerido para tareas comunes, pero ni siquiera hemos tocado la parte más importante. Marionette.Viewno maneja ninguna de las responsabilidades de renderizado por nosotros, pero Marionette tiene otros tres tipos de vistas que sí lo hacen ItemView: CollectionViewy CompositeView.

    Estos tipos de vista, que son los que realmente ampliará en su código (tenga en cuenta el comentario "Normalmente no ampliamos directamente esta vista" en todos los fragmentos de código), tomarán algunos detalles menores de configuración y luego manejarán la resto del renderizado para usted. Veremos cómo se hace todo esto en el próximo artículo. Por ahora, reflexione sobre todas estas características que le han presentado.

    (Créditos de la imagen de la portada: nyuhuhuu )

    Otras lecturas

    • Una introducción completa a Backbone.Marionette (Parte 1)
    • Una introducción completa a Backbone.Marionette (Parte 2)
    • Consejos y patrones de Backbone.js
    • Una introducción a JavaScript de pila completa

    (al, il, mrn)Explora más en

    • Codificación
    • Marcos
    • javascript





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Una introducción completa a Backbone.Marionette (Parte 3)

    Una introducción completa a Backbone.Marionette (Parte 3)

    SmashingConf UX y diseño, Amberes 2024 Índice Enlace de eventos

    programar

    es

    https://aprendeprogramando.es/static/images/programar-una-introduccion-completa-a-backbone-846-0.jpg

    2024-05-20

     

    Una introducción completa a Backbone.Marionette (Parte 3)
    Una introducción completa a Backbone.Marionette (Parte 3)

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20