web-dev-qa-db-fra.com

Existe-t-il un moyen de lier le déclencheur .change () d'un modèle à la fonction .render () d'une vue sans en créer plusieurs?

Une vue attend normalement un objet avec ces attributs avant de pouvoir effectuer le rendu:

{ el: '#someelement', model: someModel }

Une vue nous permet également de lier les événements du modèle aux fonctions de la vue:

initialize: function() {
    this.model.bind('change', this.renderFromModel, this);
},

render: function() {
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
},

renderFromModel: function() {
    var t = _.template($('#some-template').html());
    $('item-' + this.cid).html(t(this.toJSON()));
    return this;
},

Le problème est que la première fois que nous instancions une vue pour le rendu, elle attend un objet contenant un modèle; et la deuxième fois que nous rendons la vue lorsqu'elle est appelée depuis le modèle, elle ne l'est pas. Pour cette raison, je finis par créer deux fonctions render ().

Existe-t-il un meilleur moyen d'obtenir un rendu d'élément unique qui peut également répondre aux événements model.change ()?

29
rkw

je pense que vous devez vous assurer que votre méthode de rendu est toujours liée à la vue en appelant la méthode bindAll de underscore.js.

SomeView = Backbone.View.extend({
  initialize: function(){
    _.bindAll(this, "render");
    this.model.bind('change', this.render);
  },

  render: function(){
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }
});
39
Derick Bailey

Une meilleure solution consiste à utiliser la fonction listenTo :

SomeView = Backbone.View.extend({
  initialize: function(){
    this.listenTo(this.model, 'change', this.render);
  },

  render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});

De cette façon, l'objet view est au courant des liaisons qu'il a faites, et toutes peuvent être supprimées avec la fonction stopListening et n'a pas besoin d'appeler explicitement bind ou bindAll. Enfin, le code est plus propre à mon avis.

13
Blacksonic

Utilisez la méthode _.bind () pour définir la portée

 this.model.bind('change', _.bind(this.render, this));
12
ant_Ti

Depuis Backbone 0.9.2 (et peut-être plus tôt), la fonction on() ou bind() (ainsi que son homologue off() ou unbind() ) prend un paramètre context facultatif à utiliser pour this lors de son appel.

Alors,

SomeView = Backbone.View.extend({
  initialize: function(){
    _.bindAll(this, "render");
    this.model.bind('change', this.render);
  },

  render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});

peut devenir

SomeView = Backbone.View.extend({
  initialize: function(){
    this.model.bind('change', this.render, this);
  },

  render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});

Voir la documentation de on() .

6
mybuddymichael

créer une instance de modèle dans la vue

var myapp.myView  = new View({
        model: new Model
    });

et lorsque vous initialisez le Backbone.View à l'intérieur, ajoutez ceci .. quel rendu sera appelé chaque fois qu'il y aura un changement, les attributs du modèle sont ses valeurs par défaut

this.model.bind('change', this.render,this)
0
user1452840