2012-04-18 1 views
27

Quando si esegue l'override della sincronizzazione backbone, sia model/collection .save()/fetch() utilizza lo stesso metodo di sincronizzazione backbone, quindi qual è il modo migliore per verificare se ciò che riceve Backbone.sync è un modello o una collezione di modelli?Verificare se qualcosa è un modello o una raccolta in dorsale js

Per fare un esempio:

Backbone.sync = function(method, model, options){ 
    //Model here can be both a collection or a single model so 
if(model.isModel()) // there is no isModel or isCollection method 
} 

suppongo sto cercando una best practice "sicuro", ho potuto ovviamente assegno di determinati attributi o metodi che solo un modello o un insieme hanno, ma sembra hackish, non dovrebbe esserci un modo più ovvio? E probabilmente non riesco proprio a trovarlo.

Grazie!

risposta

56

Si potrebbe anche provare instanceof in questo modo:

Backbone.sync = function(method, model, options) { 
    if (model instanceof Backbone.Model) { 
    ... 
    } else if (model instanceof Backbone.Collection) { 
    ... 
    } 
} 
2

Questo è ugualmente hackish, ma una collezione Backbone ha una proprietà model e un modello no - è essa stessa un modello.

Forse un metodo più sicuro è model.toJSON() e vedere se il risultato è un oggetto o un array. Probabilmente andrai a model.toJSON() nella tua Backbone.sync personalizzata, quindi anche se questo è abbastanza costoso dal punto di vista computazionale, succederebbe comunque.

+0

Upvote perché stavo controllando su la proprietà 'length' (solo Collection ...?!?) ieri in qualche veloce codifica! Il confronto con 'model' è brillante in confronto. Haha. – eightyfive

+3

Voi ragazzi non dovreste contare su cose del genere perché potrebbero cambiare in futuro e infrangere il vostro codice. Utilizzare la parola chiave instanceof come descritto :) –

0

Si potrebbe fare qualcosa di simile.

Backbone.Model.prototype.getType = function() { 
    return "Model"; 
} 

Backbone.Collection.prototype.getType = function() { 
    return "Collection"; 
} 

if(model.getType() == "Model") {} 
if(model.getType() == "Collection"){} 
+4

È una pessima idea, quasi impossibile da mantenere quando l'applicazione diventa più complicata. E cosa succede se un oggetto ha bisogno di un metodo getType() che parla di un tipo di Car invece di un tipo di Backbone Object? –

+0

@NicolasZozol non sono d'accordo. Non vedo come sia difficile da mantenere e il secondo punto è semplicemente ingiusto. Puoi chiamare i metodi di cui sopra come vuoi. Ad esempio 'getBackboneObjectType', che sicuramente non causerà conflitti di denominazione. –

+0

Il motivo per cui ciò è negativo, è che l'implementatore deve tenere traccia dei tipi di oggetto contenuti in una libreria di terze parti e creare un nuovo prototipo getType ogni volta che viene introdotto un nuovo tipo nelle future versioni di Backbone. Inoltre, ti esponi a errori di ortografia dei tipi senza un vero e semplice modo per rilevarli (poiché tutto viene eseguito tramite confronti tra stringhe.) L'uso di instanceof consente ai compilatori JavaScript (come node.js) di rilevare eventuali errori di ortografia e la compilazione fallita dovrebbe essere oggetto i nomi cambiano in una versione aggiornata di Backbone, rendendo più semplice l'identificazione delle modifiche. –

10

@ risposta di fiskers7 lavora con estensione profonda:

 var Item = Backbone.Model.extend({ 
      className : 'Item', 
      size :10 
     }); 

     var VerySmallItem = Item.extend({ 
      size :0.1 
     }); 

     var item = new Item(); 
     var verySmall = new VerySmallItem(); 

     alert("item is Model ?" + (item instanceof Backbone.Model)); //true 
     alert("verySmall is Model ?" + (verySmall instanceof Backbone.Model)); //true 
0

io non sono del tutto sicuro di come mi sento su questo perché sembra un po 'schifoso, ma non riesco a pensare esattamente perché sarebbe davvero pessimo al momento.

Decisamente semplice e più veloce di un "instanceof" di controllo (sto supponendo che non chiamerai altre funzioni "isBBModel/Collection" a oggetti?)

Backbone.Model.prototype.isBBCollection = function() { return false; } 
Backbone.Model.prototype.isBBModel = function() { return true; } 
Backbone.Collection.prototype.isBBCollection = function() { return true; } 
Backbone.Collection.prototype.isBBModel = function() { return false; }