2011-10-20 16 views
14

Wyobraźmy sobie prosty model szkieletu jakbackbone.js - niestandardowe ustawiaczy

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

Staram się znaleźć sposób, aby zawsze sprawiają sklepu modelu nazwę małymi literami, niezależnie od wejścia do tego celu. tj.,

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

Jaki jest najlepszy sposób na zrobienie tego? Oto wszystko, co mogłem myśleć:

  1. przesłonić „zestaw” metoda
  2. Użyj „SantizedModel”, który wykrywa zmiany w tym modelu bazowego i przechowuje odkażane wejść. Cały kod widoku zostanie wówczas przekazany temu odkażanemu modelowi.

Specyficzny „do małymi literami” przykład mówiłem technicznie może być lepiej obsługiwane przez widoku podczas pobierania, ale wyobrazić sobie inny przypadek, w którym, na przykład, użytkownik wprowadza wartości w funtach i chcę tylko do przechowywania wartości w $ s w mojej bazie danych. Mogą istnieć różne widoki tego samego modelu i nie chcę robić "toLowerCase" wszędzie, gdzie jest używany.

Myśli?

Odpowiedz

5

Byłoby hack, ponieważ nie jest to co to było robione dla, ale zawsze można użyć walidatora dla tego:

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

     return true; 
    } 
}) 

Funkcja validate dostanie nazwie (o ile silent opcja nie jest ustawiona), zanim wartość zostanie ustawiona w modelu, więc daje szansę na zmutowanie danych, zanim zostanie naprawdę ustawiona.

+0

Dzięki. Rozważałem to również, ale wydawało się to krokiem wstecz, jeśli chodzi o nadawanie mu czytelności - przesłonięcie ustawionej funkcji lub dodanie nowej funkcji "setProperty", która ustawia ją małymi literami, a następnie przekazuje ją do zestawu szkieletowego, może być lepsza. Chyba że czegoś mi brakuje? – Naren

+0

Z pewnością nie ma nic złego w przesłonięciu metody "set", aby zrobić to, co trzeba zrobić ... trochę wstępnego przetwarzania przed zbiorem? Możesz nawet rozważyć rozszerzenie 'Backbone.Model.prototype.set', aby zadzwonić do niektórych preprocesorów, jeśli pasują ... coś takiego: https://gist.github.com/1310972 –

+0

sprawdzanie poprawności jest wywoływane tylko dla metody zapisu lub jeśli ustawione jest options.validate = true. (cichy nie jest tutaj używany, ale odpowiedź jest dość stara) – webstrap

10

UPDATE: można użyć wtyczki: https://github.com/berzniz/backbone.getters.setters


Można zastąpić zestaw metody takie jak to (dodać go do swoich modelach):

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

zamiast pętli polecam if (attrs.name) attrs.name = attrs.name.toLowerCase(); – webstrap

+0

Należy zauważyć, że jeśli pierwszym parametrem jest obiekt, ustawienie atrybutów jest delegowane do 'set' z ciągiem jako pierwszym parametrem. Zatem normalizacja jest wymagana tylko wtedy, gdy pierwszym parametrem jest ciąg znaków. – Webthusiast

3

Nie trąbienie mój własny róg, ale I created a Backbone model z właściwościami "komputerowymi", aby ominąć to. Innymi słowy:

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(); 

    } 
    } 
}) 

Możesz również wykryć zmiany we właściwościach obliczeniowych i traktować je jako zwykłe.

The plugin Bereznitskey mentioned to również prawidłowe podejście.

+0

Próbuję tego teraz i jest to echo mojej rzeczywistej funkcji raczej niż wartość zwracana. 'defaults: {distance: function() {return 10; } }, 'then' console.log (this.model.get ('distance')); '?? – trapper

+0

@trapper - czy wyciągasz z "BasecomputedModel" z połączonego githuba? – Naren