2011-10-20 23 views
14

想象一下,一個簡單的模型骨幹像Backbone.js的 - 自定義的制定者

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

我試圖找到一種方法,始終使模型店提供了小寫的名字,不論輸入。即,

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

什麼是這樣做的最佳方式?這是所有我能想到的:

  1. 覆蓋「設置」方法
  2. 使用「SantizedModel」,它監聽在此基礎上模式的變化和存儲消毒的投入。所有視圖代碼然後將被傳遞給這個消毒模型。

特定的「小寫」比如我提到技術上可能由視圖來更好地處理在檢索它,但是想象一下,比方說,用戶在磅輸入值,並在那裏,我只想要存儲的值在不同的情況下, $ s在我的數據庫中。對於同一個模型也可能有不同的觀點,我不想在它使用的任何地方都做一個「toLowerCase」。

的思考?

回答

5

這將是一個黑客,因爲這不是什麼被造的,但你總是使用這個驗證:

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

     return true; 
    } 
}) 

的驗證功能將被調用(只要silent選項未設置)之前,該值在模型中設置,因此它使您有機會在數據真正設置之前對其進行變異。

+0

謝謝。我也考慮過這個問題,但是這樣做似乎在使其可讀性方面退步 - 重寫set函數或添加一個新的「setProperty」函數,將其設置爲小寫,然後將其傳遞到主幹集合可能會更好。除非我錯過了什麼? – Naren

+0

重寫'set'方法以完成你需要完成的任務是沒有錯的......在集合之前進行一些預處理?你甚至可以考慮擴展'Backbone.Model.prototype.set'來調用一些預處理器,如果它們匹配的話......類似這樣的:https://gist.github.com/1310972 –

+0

validate只被調用save方法或者如果設置了options.validate = true。 (沉默不在這裏使用,但答案是相當老) – webstrap

10

UPDATE:您可以使用插件:https://github.com/berzniz/backbone.getters.setters


您可以覆蓋這樣的(它添加到您的模型)的設置方法:

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

,而不是一個循環,我會建議如果(attrs.name)attrs.name = attrs.name。toLowerCase(); – webstrap

+0

請注意,如果第一個參數是一個對象,那麼屬性的設置將作爲第一個參數委託給'set'字符串。所以只有第一個參數是字符串時才需要標準化。 – Webthusiast

3

不嘟嘟我自己的號角,但I created a Backbone model與「計算」屬性來解決這個問題。換句話說

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

    } 
    } 
}) 

您還偵聽計算性能的變化和非常簡單,只是把它當作一個普通一個。

The plugin Bereznitskey mentioned也是一種有效的方法。

+0

我現在試着這個,它迴應我的實際功能,而不是返回值。 'defaults:{distance:function(){return 10; }然後'console.log(this.model.get('distance'));'?? – trapper

+0

@trapper - 你是否從鏈接的github的「BasecomputedModel」擴展? – Naren