web-dev-qa-db-fra.com

Comment définir une propriété dynamique sur un modèle avec Backbone.js

Histoire: J'ai beaucoup de propriétés à définir. Comme ils ont des similitudes, je choisis de lire la classe à laquelle appartient inputbox comme nom de propriété.

Problème: Une propriété dynamique d'un objet peut être définie, tout comme un tableau associatif. Donc je pourrais faire 

var customattribute = this.$el.parents('div').attr('id');
var value = $(e.currentTarget()).val();

this.model.attributes[customattribute] = value;

Mais cela ne déclencherait pas un événement de changement du modèle. Je pourrais déclencher manuellement un événement change, mais cela ne mettrait pas à jour this.model.changedAttributes (), je ne devais définir que l'attribut modifié, pas tous les attributs.

Bien sûr, cela ne fonctionne pas non plus:

this.model.set(customattribute: value);

Alors, comment pourrais-je gérer ce problème?

J'ai beaucoup (plus de 200) attributs qui peuvent être définis, je ne voudrais pas créer des eventlisteners distincts pour chaque attribut, à moins que ce ne soit la seule façon.

Code:

var Display = Backbone.View.extend({
    className: 'display',
    events: {
        'slide .slider' : 'sliderHandler'
    },
    initialize: function(){
        _.bindAll(this, 'render', 'sliderHandler','update');
        this.model.on('change',this.update, this);
    },
    render: function(){
        this.$el.html(_.template(html, {}));
        this.$('.slider').slider();

        return this;
    },
    sliderHandler: function(e){
        var slider = $(e.currentTarget);
        var property = slider.parents('div').attr('id');
        var value = slider.slider('value');

        this.model.attributes[property] = value;            
    },
    update: function(){
        console.log(this.model.changedAttributes());
        //get changed attribute + value here

    },
});

Modifier:

Les deux réponses ci-dessous l'ont résolu. Mappez les attributs sur un objet et attribuez-les à Backbone. J'ai aussi trouvé une autre solution. Au lieu d'un objet, model.set () accepte également un tableau.

model.set(customattribute, value, customattribute2, value2);
15
Jareish

Je ne suis pas sûr de bien comprendre votre problème, mais: Si vous souhaitez mettre à jour un attribut, il suffit de:

this.model.set({
     customattribute: value
});

Si vous souhaitez que le paramètre ne déclenche pas un événement, vous pouvez passer une option silencieuse, comme ceci:

this.model.set({
     customattribute: value
}, {silent:true});

J'espère que ça t'aide.

MIS À JOUR:

Autrement:

 var map = {};
 map[customattribute] = value;
 this.model.set(map);
26
Aito

Tu dois faire ça

var attributeName = this.$el.parents('div').attr('id');
var value = $(e.currentTarget()).val();
var attribute = {};
attribute[attributeName] = value;
this.model.set(attribute);

si attribut était "test" et valeur 'valeur', ce serait la même chose que

this.model.set({test: 'value'});

ce qui définit correctement l'attribut et se propage à votre vue grâce à l'événement de changement de modèle

5
James Kyburz

À partir de Backbone 0.9.0 (30 janvier 2012) , model.set ( source ) accepte un clé, un valeur, et un objet options.

this.model.set(attributeName, value, { silent: true });

est équivalent à

var attr = {};
attr[attributeName] = value;
this.model.set(attr, { silent: true });
0
Emile Bergeron