2011-10-20 28 views
14

Hãy tưởng tượng một mô hình xương sống đơn giản nhưBackbone.js - setters tùy chỉnh

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

Tôi đang cố gắng để tìm một cách để luôn luôn làm cho các cửa hàng mô hình tên trong trường hợp thấp hơn-không phụ thuộc vào đầu vào được cung cấp. tức là,

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

Cách tốt nhất để làm điều này là gì? Dưới đây là tất cả tôi có thể nghĩ:

  1. Ghi đè các "thiết lập" phương pháp
  2. Sử dụng một "SantizedModel" mà nghe cho những thay đổi về mô hình cơ sở này và lưu trữ các đầu vào vệ sinh. Sau đó, tất cả mã xem sẽ được chuyển qua mô hình đã được vệ sinh này.

Ví dụ cụ thể "xuống thấp hơn" tôi đã đề cập về mặt kỹ thuật có thể được xử lý tốt hơn theo chế độ xem trong khi truy xuất nó, nhưng hãy tưởng tượng một trường hợp khác, trong đó, người dùng nhập giá trị vào Bảng Anh và tôi chỉ muốn lưu trữ các giá trị trong $ s trong cơ sở dữ liệu của tôi. Cũng có thể có các chế độ xem khác nhau cho cùng một mô hình và tôi không muốn phải thực hiện "toLowerCase" ở mọi nơi được sử dụng.

Suy nghĩ?

Trả lời

5

Nó sẽ là một hack, bởi vì đây không phải là những gì nó đã được thực hiện cho, nhưng bạn luôn có thể sử dụng một validator cho việc này:

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

     return true; 
    } 
}) 

Chức năng validate sẽ được gọi là (miễn là silent tùy chọn không được đặt) trước khi giá trị được đặt trong mô hình, do đó, nó cho bạn cơ hội để thay đổi dữ liệu trước khi nó thực sự được đặt.

+0

Cảm ơn. Tôi cũng xem xét điều này, nhưng điều này dường như lùi lại về mặt làm cho nó có thể đọc được - ghi đè hàm thiết lập hoặc thêm hàm setProperty mới đặt trong chữ thường và sau đó chuyển nó vào bộ xương sống có thể tốt hơn. Trừ khi tôi đang thiếu một cái gì đó? – Naren

+0

Chắc chắn không có gì sai với việc ghi đè phương thức 'set' để hoàn thành những gì bạn cần làm ... một số tiền xử lý trước khi thiết lập? Bạn thậm chí có thể xem xét mở rộng 'Backbone.Model.prototype.set' để gọi một số bộ xử lý trước nếu chúng khớp ... một cái gì đó như thế này: https://gist.github.com/1310972 –

+0

xác thực chỉ được gọi cho phương thức lưu hoặc nếu options.validate = true được đặt. (im lặng không được sử dụng ở đây, nhưng câu trả lời là khá cũ) – webstrap

10

CẬP NHẬT: bạn có thể sử dụng các plug-in: https://github.com/berzniz/backbone.getters.setters


Bạn có thể ghi đè lên phương thức thiết lập như thế này (thêm nó vào mô hình của bạn):

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

thay vì một vòng lặp tôi sẽ khuyên bạn nên nếu (attrs.name) attrs.name = attrs.name.toLowerCase(); – webstrap

+0

Lưu ý rằng nếu tham số đầu tiên là một đối tượng, thiết lập của các thuộc tính được giao cho 'set' với một chuỗi như tham số đầu tiên. Vì vậy, bình thường hóa chỉ cần thiết nếu tham số đầu tiên là một chuỗi. – Webthusiast

3

Không thổi còi sừng của riêng tôi, nhưng I created a Backbone model với thuộc tính "Tính toán" để giải quyết vấn đề này. Nói cách khác,

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

    } 
    } 
}) 

Bạn cũng nghe những thay đổi về tính toán và khá nhiều chỉ coi đây là thông thường.

The plugin Bereznitskey mentioned cũng là phương pháp hợp lệ.

+0

Tôi đang thử điều này ngay bây giờ và nó đang lặp lại chức năng thực tế của tôi thay vì giá trị trả lại. 'defaults: {distance: function() {return 10; } }, 'then' console.log (this.model.get ('distance'));' ?? – trapper

+0

@trapper - bạn có đang mở rộng từ "BasecomputedModel" từ github được liên kết không? – Naren