43 votes

Exclure les propriétés du modèle lors de la synchronisation (Backbone.js)

Est-il possible d'exclure certains biens de mon modèle quand je synchroniser?

Par exemple, je garde dans mon modèle d'information au sujet de certains de l'état d'affichage. Disons que j'ai un sélecteur de module et ce module juste passer un selected attributs sur mon modèle. Plus tard, quand je l'appelle .save() sur ma collection, je veux ignorer la valeur de selected et de l'exclure de la synchronisation avec le serveur.

Est-il un moyen propre de le faire?

(Laissez-moi savoir si vous souhaitez plus de détails)

47voto

Simon Boudrias Points 12696

Cela semble être la meilleure solution (basée sur la question référencée @nikoshr)

 Backbone.Model.extend({

    // Overwrite save function
    save: function(attrs, options) {
        options || (options = {});
        attrs || (attrs = _.clone(this.attributes));

        // Filter the data to send to the server
        delete attrs.selected;
        delete attrs.dontSync;

        options.data = JSON.stringify(attrs);

        // Proxy the call to the original save function
        Backbone.Model.prototype.save.call(this, attrs, options);
    }
});
 

Nous écrasons donc la fonction de sauvegarde sur l'instance du modèle, mais nous filtrons simplement les données dont nous n'avons pas besoin, puis nous transmettons cette fonction à la fonction prototype parente.

35voto

byoungb Points 614

Dans le trait de Soulignement 1.3.3 ils ont ajouté de sélection et en 1.4.0 ils ont ajouté omettre de ce qui peut être utilisé très simplement de remplacer votre modèle toJSON fonction de liste blanche attributs _.pick ou liste noire des attributs avec _.omit.

Et depuis toJSON est utilisé par la commande sync pour transmettre les données au serveur, je pense que c'est une bonne solution aussi longtemps que vous ne souhaitez pas que ces domaines où que vous utilisez toJSON.

Backbone.Model.extend({
    blacklist: ['selected',],
    toJSON: function(options) {
        return _.omit(this.attributes, this.blacklist);
    },
});

11voto

oak Points 407

ma solution combine tout ce qui précède. il suffit d’utiliser la liste blanche au lieu du noir .. c’est une bonne règle en général

définir

           attrWhiteList:['id','biography','status'],
 

puis écrasez la sauvegarde

   save: function(attrs, options) {
    options || (options = {});

 //here is whitelist or all
    if (this.attrWhiteList != null )
          // Filter the data to send to the server
             whitelisted =  _.pick(this.attributes, this.attrWhiteList);
    else  
        whitelisted =this.attributes;
    /* it seems that if you override save you lose some headers and the ajax call changes*/
    // get data
    options.data = JSON.stringify(whitelisted);

    if ((this.get('id') == 0) || (this.get('id') == null)) 
        options.type = "POST"
    else
        options.type = "PUT";


    options.contentType = "application/json";
     //        options.headers =  { 
     //            'Accept': 'application/json',
     //            'Content-Type': 'application/json' 
     //        },

    // Proxy the call to the original save function
   return  Backbone.Model.prototype.save.call(this, attrs, options);
},
 

6voto

Pascal Points 142

En fait, il existe un moyen beaucoup plus simple de réaliser ceci sans vous embêter avec épine dorsale de l'enregistrer ou de la fonction de synchronisation depuis vous le feriez pas s'attendre à ce comportement sera permanente

si vous regardez backbone.js ligne 1145, vous verrez que

// Ensure that we have the appropriate request data.
    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(options.attrs || model.toJSON(options));
    }

Ce qui signifie que vous pouvez remplacer la partie données de la xhr en mettant des données dans vos options

Depuis épine dorsale enregistrer nécessite modèle.enregistrer([attributs], [options])

Mais rappelez-vous que les attributs id pourrait être essentiel à une bonne économie

Exemple

model.save( {}, { data: JSON.stringify(data) } ) ; 

Donc, vous devriez être en train de faire quelque chose comme ceci

var data = { id : model.id , otherAttributes : 'value' }  ;  
model.save( {}, { data : JSON.stringify(data) } );

Ce faire le truc très bien pour moi et peut être utilisé avec n'importe quel squelette avec xhr comme extraire, enregistrer, supprimer, ...

3voto

ssorallen Points 7562

Sur la base de plusieurs réponses, cela représente des cas d'objets nuls et une condition conditionnelle dans Backbone qui n'a pas envoyé le contentType si options.data est déjà défini:

 EDITABLE_ATTRIBUTES = ["name", "birthdate", "favoriteFood"];

...

save: function(attrs, options) {
  // `options` is an optional argument but is always needed here
  options || (options = {});

  var allAttrs = _.extend({}, this.attributes, attrs);
  var allowedAttrs = _.pick(allAttrs, EDITABLE_ATTRIBUTES);

  // If `options.data` is set, Backbone does not attempt to infer the content
  // type and leaves it null. Set it explicitly as `application/json`.
  options.contentType = "application/json";
  options.data = JSON.stringify(allowedAttrs);

  return Backbone.Model.prototype.save.call(
    this, allowedAttrs, options);
},
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X