2011-10-20 12 views
14

Imagine un modelo de espina dorsal simple comoBackbone.js - set personalizados

window.model= Backbone.Model.extend({ 
    defaults:{ 
     name: "", 
     date: new Date().valueOf() 
    } 
}) 

Estoy tratando de encontrar una manera de hacer siempre el modelo de tienda el nombre en minúsculas, independientemente de la entrada proporcionada. es decir,

model.set({name: "AbCd"}) 
model.get("name") // prints "AbCd" = current behavior 
model.get("name") // print "abcd" = required behavior 

¿Cuál es la mejor manera de hacerlo? Aquí está todo lo que podía pensar:

  1. Sustituir el "ajuste" método
  2. Use un "SantizedModel", que escucha los cambios en este modelo base y almacena las entradas desinfectados. Todo el código de vista se pasaría en este modelo sanitizado.

El ejemplo específico "minúsculas" que mencioné puede ser mejor manejado técnicamente por la vista al recuperarlo, pero imagine un caso diferente donde, digamos, el usuario ingresa valores en libras y solo quiero almacenar valores en $ s en mi base de datos. También puede haber diferentes vistas para el mismo modelo y no quiero tener que hacer un "toLowerCase" donde quiera que se use.

¿Pensamientos?

Respuesta

5

Sería un truco, porque esto no es lo que fue hecho, pero siempre se podría utilizar un validador para esto:

window.model= Backbone.Model.extend({ 
    validate: function(attrs) { 
     if(attrs.name) { 
     attrs.name = attrs.name.toLowerCase() 
     } 

     return true; 
    } 
}) 

La función de validación se llamará (siempre y cuando el silent la opción no está configurada) antes de establecer el valor en el modelo, por lo que le da la oportunidad de cambiar los datos antes de que realmente se establezcan.

+0

Gracias. Consideré esto también, pero esto parecía ser un paso atrás en términos de hacer que fuera legible, anulando la función establecida o agregando una nueva función "setProperty" que lo establece en minúscula y luego lo pasa al conjunto de la red troncal podría ser mejor. A menos que me esté perdiendo algo? – Naren

+0

No hay nada de malo en anular el método 'set' para hacer lo que necesita hacer ... ¿algún preprocesamiento antes del set? Incluso podría considerar extender 'Backbone.Model.prototype.set' para llamar a algunos preprocesadores si coinciden ... algo como esto: https://gist.github.com/1310972 –

+0

validate solo se llama para guardar el método o si se establece options.validate = true. (el silencio no se usa aquí, pero la respuesta es bastante antigua) – webstrap

10

ACTUALIZACIÓN: puede utilizar el plug-in: https://github.com/berzniz/backbone.getters.setters


Puede reemplazar el método conjunto como éste (añadirlo a sus modelos):

set: function(key, value, options) { 
    // Normalize the key-value into an object 
    if (_.isObject(key) || key == null) { 
     attrs = key; 
     options = value; 
    } else { 
     attrs = {}; 
     attrs[key] = value; 
    } 

    // Go over all the set attributes and make your changes 
    for (attr in attrs) { 
     if (attr == 'name') { 
      attrs['name'] = attrs['name'].toLowerCase(); 
     } 
    } 

    return Backbone.Model.prototype.set.call(this, attrs, options); 
} 
+3

en lugar de un bucle que recomendaría si (attrs.name) attrs.name = attrs.name.toLowerCase(); – webstrap

+0

Tenga en cuenta que si el primer parámetro es un objeto, la configuración de los atributos se delega a 'set' con una cadena como primer parámetro. Entonces la normalización solo es necesaria si el primer parámetro es una cadena. – Webthusiast

3

No a sonar mi propio cuerno, pero I created a Backbone model con propiedades "Calculadas" para evitar esto. En otras palabras

var bm = Backbone.Model.extend({ 
    defaults: { 
    fullName: function(){return this.firstName + " " + this.lastName}, 
    lowerCaseName: function(){ 
     //Should probably belong in the view 
     return this.firstName.toLowerCase(); 

    } 
    } 
}) 

También escuchar los cambios en las propiedades calculadas y prácticamente sólo tratar esto como una normal.

The plugin Bereznitskey mentioned es también un enfoque válido.

+0

Estoy intentando esto ahora y está haciendo eco de mi función real más que del valor de retorno. 'por defecto: {distance: function() {return 10; } }, 'then' console.log (this.model.get ('distance')) '' ?? – trapper

+0

@trapper: ¿se está extendiendo desde el "BasecomputedModel" del github vinculado? – Naren