¿No se reconoce el activador de evento personalizado de backbone?

Estoy aprendiendo Backbone.js por primera vez y tengo un problema al intentar que se active un evento personalizado (o que la Vista reconozca cuándo se ha activado)?

Puedes ver mi código de colección aquí: https://github.com/Integralist/Backbone-Playground/blob/master/Assets/Scripts/App/main.js#L72-86 que cuando se inicializa desencadena una costumbre collection:init evento.

var Contacts = Backbone.Collection.extend({
    model: Contact,

    initialize: function(){
        this.trigger('collection:init');
        this.bind('add', this.model_added, this);
    },

    model_added: function(){
        console.log('A new model has been created so trigger an event for the View to update the <select> menu');
    }
});

Pero más adelante en mi vista donde estoy escuchando ese evento no puedo obtener la función populate para disparar: https://github.com/Integralist/Backbone-Playground/blob/master/Assets/Scripts/App/main.js#L90-107

var ContactsView = Backbone.View.extend({
    initialize: function(){
        console.log(contacts.models, 'get initial model data and populate the select menu?');
    },

    events: {
        'collection:init': 'populate',
        'change select': 'displaySelected'
    },

    populate: function(){
        console.log('populate the <select> with initial Model data');
    },

    displaySelected: function (event) {
        console.log('get model data and display selected user', event);
    }
});

¿Alguna idea de lo que estoy haciendo mal?

preguntado el 28 de julio de 12 a las 14:07

Hola, ¿la vista recibe la colección a través del constructor? durante el método de inicialización dentro de la vista, ¿se ha suscrito al evento como este? this.collection.on("init",this.populate) -

1 Respuestas

El hash de eventos en una vista se usa para vincular eventos del DOM a su vista, por ejemplo, eventos generados por los elementos en su vista renderizada. Para escuchar los eventos generados por su colección, deberá configurarlos manualmente:

var ContactsView = Backbone.View.extend({
    initialize: function(){
        contacts.on("collection:init",this.populate,this);
    }
    ...
});

Tenga en cuenta que está utilizando una variable de contactos globales, le recomendaría usar mecanismos de Backbone y pasar su colección al constructor, como lo hace con el:

var ContactsView = Backbone.View.extend({
    initialize: function(){
        console.log(this.collection.models);
        this.collection.on("collection:init",this.populate,this);
    }
    ...
});

var contacts_view = new ContactsView({
    el: $('#view-contacts'),
    collection:contacts
});

Como dijo @mu en los comentarios, tal como está, su evento no hará nada ya que lo activa en el método de inicialización de la colección, que el constructor de la colección llama automáticamente, por lo tanto, antes de que pueda vincular cualquier cosa en la vista. Vea este violín para visualizar el orden de llamada: http://jsfiddle.net/yRuCN/

Actívelo en otro lugar o, si leí correctamente su intención, (probablemente) quiera usar el evento de reinicio incorporado:

var ContactsView = Backbone.View.extend({
    initialize: function(){
        this.collection.on("reset",this.populate,this);
    }
    ...
});

Ver http://jsfiddle.net/yRuCN/1/ para un ejemplo con usos potenciales.

Respondido 29 Jul 12, 15:07

this.collection.on("collection:init",this.populate,this); seguirá teniendo un problema, ¿no? La colección siempre será inicializada (y "collection:init" activado) antes de que algo pueda vincularse a ese evento. - mu es demasiado corto

@mu Tienes toda la razón, no estaba seguro de cómo explicar eso, por eso agregué la mención sobre el evento de reinicio. Editaré mi respuesta y agregaré tu comentario, de alguna manera :) - Nikoshr

Creo que tienes razón sobre el evento de reinicio. Y el model_added probablemente debería estar justo en la vista también. - mu es demasiado corto

@Integralist Eso es lo que Mu y yo discutimos en los comentarios anteriores, activar un evento en el método de inicialización no lo llevará a ninguna parte, nada puede escucharlo porque la inicialización es parte del constructor. Verifique el primer Fiddle que acabo de agregar para ver qué sucede cuando crea una colección. El segundo Fiddle debería indicarle la dirección de posibles soluciones. - Nikoshr

@Integralist y un último Fiddle para demostrar un evento personalizado jsfiddle.net/yRuCN/2 - Nikoshr

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.