5

Actualmente estoy usando Backbone.Mediator para aprovechar el beneficio del patrón Mediator en mi proyecto Backbone + RequireJS; sin embargo, encontré un comportamiento peculiar del Patrón que no estoy tan seguro de si es "por diseño", o más bien, no el comportamiento estándar del Patrón del Mediador, sino un error en el complemento.Patrón Backbone + RequireJS + Mediator resultó en cortocircuito de la lógica de la vista y el bucle infinito

Como un ejemplo artificial:

Módulo AMD 1

var View1 = Backbone.View.extend({ 
    ... 
    events: { 
     'click div: switchList' 
    }, 
    switchList: function() { 
     Backbone.Mediator.pub('list:switch'); 
    } 
}); 

Módulo AMD 2

var View2 = Backbone.View.extend({ 
    ... 
    subscriptions: { 
     'list:switch': 'shrinkDiv' 
    }, 
    shrinkDiv: function() { 
     Backbone.Mediator.pub('div:shrink'); 
     this.shrinkAndMore(); 
    } 
}); 

return View2; 

Módulo AMD 3

define(function(require) { 
    var View2 = require(**AMD Module 2**); 

    var View3 = Backbone.View.extend({ 
     ... 
     subscriptions: { 
      'div:shrink': 'createSiblingDiv' 
     }, 
     createSiblingDiv: function() { 
      this.siblingView = new View2(); 
      this.$el.after(this.siblingView.$el); 
      this.siblingView.render(); 
     } 
    }); 
}); 

pensé que sería el siguiente:

     **View1**.switchList(); 
         │ 
Channel 'list:switch' │ 
         ↓ 
         **View2**.shrinkDiv(); 
         │ 
         ├─┐ 
         │ │ Channel 'div:shrink' 
         │ ↓ 
         │ **View3**.createSiblingDiv(); 
         │ │ 
         │ └──→ "SiblingDiv created and rendered" 
         │ 
         └────→ "View2 Div shrinked and more" 

Sin embargo, la verdad es que ya SiblingDiv es otro ejemplo de Vista2, que se adhiere a 'lista: Interruptor' Canal, SiblingDiv, inmediatamente después de su creación , también será activado por la señal de evento que aún transpira en Channel 'list: switch' (que solo cesará después de la ejecución de **View2**.shrinkAndMore();).

lo tanto, el flujo real de código es así:

     **View1**.switchList(); 
         │ 
Channel 'list:switch' │ 
         ↓ 
         **View2**.shrinkDiv(); ←──────────────────┐ 
         │           │ 
         ├─┐          │ 
         │ │ Channel 'div:shrink'     │ 
         │ ↓          │ 
         │ **View3**.createSiblingDiv();   │ 
         │ │          │ 
         │ └──→ "SiblingDiv created and rendered" ─┘ 
         │ 
         └────→ "View2 Div shrinked and more" 

Un bucle infinito ... Ooops!

que era capaz de hacer cosas mi forma de trabajo con algunas modificaciones a mi código:

AMD Módulo 2 Modded

var View2 = Backbone.View.extend({ 
    initialize: function() {         // new code 
     if (this.options.subscriptions) {     // new code 
      this.subscriptions = this.options.subscriptions; // new code 
     }             // new code 
    },              // new code 
    ... 
    subscriptions: { 
     'list:switch': 'shrinkDiv' 
    }, 
    shrinkDiv: function() { 
     Backbone.Mediator.pub('div:shrink'); 
     this.shrinkAndMore(); 
    } 
}); 

return View2; 

AMD Módulo 3 Modded

define(function(require) { 
    var View2 = require(**AMD Module 2**); 

    var View3 = Backbone.View.extend({ 
     ... 
     subscriptions: { 
      'div:shrink': 'createSiblingDiv' 
     }, 
     createSiblingDiv: function() { 
      this.siblingView = new View2({  // new code 
       subscriptions: {}     // new code 
      });         // new code 
      this.$el.after(this.siblingView.$el); 
      this.siblingView.render(); 
     } 
    }); 
}); 

Pero estoy muy interesado en comprender que si el comportamiento de bucle infinito (nuevo Objeto creado durante una emisión de señal de evento también se desencadenará por esa misma señal) se considera "estándar" en la metodología de patrón de mediador? ¿O todo esto es solo un error en la parte del complemento?

Respuesta

5

Parece que esto es un error en el complemento. Eche un vistazo a this line. Pasará por todos los eventos que se registraron en este canal. El problema es que se detiene cuando se llaman todos los eventos registrados y comprueba las longitudes de la matriz de los eventos registrados en cada paso de bucle.¿Cuál es tan ocurre es:

  1. dispare el evento
  2. su evento registrado se llama
  3. se crea una nueva instancia y se registrará automáticamente al canal
  4. este aumento de la longitud de la matriz en un
  5. así que en vez de poner fin al bucle que se llame a la escucha de la opinión de la recién creada
  6. volver a 3.

Cambio de la línea a:

for (var i = 0, l = channels[channel].length; i < l; i++) { 

debería solucionar esta causa se obtiene la longitud de la matriz al comienzo. Agregar un nuevo elemento no terminará en un bucle infinito.

+0

Buena captura, parece un error por su naturaleza ... gracias por descubrir esto y la gran respuesta = D – Kay

Cuestiones relacionadas