2012-11-13 3 views
1

Meteor 프로젝트에서 Session 변수를 동적으로 업데이트하는 모델을 작성하려고합니다. 나는 일반 JSON 백본 모델에 저장되지 않아야 함을 알고, 그래서 나는과 같이 설정 특별 모델이 있습니다백본 모델에서 '변경'이벤트는 어떻게 처리됩니까?

"가격"과 "날짜"와
initialize : function() { 
    // Log the changed properties 
    this.on('change', function (model, options) { 
     for (var i in options.changes) 
      this.display(i); 
     Session.set('NewSpecial', model); 
    }); 
}, 
//Attributes 
defaults: { 
    "Product" : null, 
    "ShortDescription" : null, 
    "Category" : "food", 
    "Price" : new PriceModel, 
    "Date" : new DateModel, 
    "Uses" : 0, 
    "Tags" : [], 
    "Contributor" : null 
}, 

가 자신의 모델에 저장되는 :

//Price model for use within Special 
var PriceModel = Backbone.Model.extend({ 
    defaults : { 
     "Regular" : null, 
     "Special" : null, 
     "PercentOff" : null 
    } 
}); 

//Date model for use within Special 
var DateModel = Backbone.Model.extend({ 
    defaults : { 
     "StartTime" : null, 
     "EndTime" : null, 
     "HumanTimeRange" : null 
    } 
}); 

그림과 같이 특수 모델의 속성이 변경되면 변경된 속성에 대한 표시를 호출 한 다음 세션 var를 모델로 설정해야합니다. 그러나 DateModel 또는 PriceModel이 변경되면 Special 모델에서 변경 이벤트가 트리거되지 않습니다. 각 "DateModel"및 "PriceModel"은 this.on('change', ...) 메서드를 가지고 Special.set(attribute, thisModel) 메서드를 호출해야합니까? 아니면이 문제를 해결할 다른 방법이 있습니까?

답변

2

몇 가지 문제점이 있습니다. 모든

먼저 defaults :

defaults: { 
    "Product" : null, 
    "ShortDescription" : null, 
    "Category" : "food", 
    "Price" : new PriceModel, 
    "Date" : new DateModel, 
    "Uses" : 0, 
    "Tags" : [], 
    "Contributor" : null 
} 

PriceModel, 하나 DateModel으로 끝날 것이며, 하나 개의 태그 배열은 해당 모델의 모든 인스턴스에 의해 공유되고. A defaults 개체는 모델의 특성에 얕은 복사 및 병합되며 defaults의 값은 복제되거나 복제되지 않고 그대로있는 그대로 복사됩니다. 당신이 distinced Price, DateTags 값은 다음 defaults하는 기능을 사용하려면 다음

defaults: function() { 
    return { 
     "Product" : null, 
     "ShortDescription" : null, 
     "Category" : "food", 
     "Price" : new PriceModel, 
     "Date" : new DateModel, 
     "Uses" : 0, 
     "Tags" : [], 
     "Contributor" : null 
    }; 
} 

두 번째 문제는 set가 수단을 변경 무엇 상당히 단순한 전망을 가지고 있다는 것입니다. 당신이 source for set 살펴있는 경우이가 표시됩니다

// If the new and previous value differ, record the change. If not, 
// then remove changes for this attribute. 
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) { 
    this.changed[attr] = val; 
    if (!silent) this._pending[attr] = true; 
} else { 
    delete this.changed[attr]; 
    delete this._pending[attr]; 
    if (!changing) delete this._changes[attr]; 
} 

_.isEqual 그 무엇인가를 인식하지 않습니다 당신의 Price 또는 Date 내부를 변경하거나 추가하거나 Tags에서 뭔가를 제거했다고했다. 이 같은 일을 할 경우

p = new PriceModel(...); 
m.set('Price', p) 

다음 mPrice가 변경된 것을 발견하지만 경우 :

p = m.get('Price'); 
p.set(...); 
m.set('Price', p); 

다음 mPrice가 변경된 것을 인식하지 않습니다; 귀하의 모델은 Price에있는 이벤트에 자동으로 바인딩되지 않으므로 p.set(...) 호출을 인식하지 못하며 p = p을 말하는 멋진 방법이기 때문에 m.set('Price', p)을 변경으로 인식하지 못합니다.

당신은 setget에서 온 Tags 배열을 제공하지 않음으로써이 변화의 일부 문제를 해결할 수있다; 복사본을 만들고 복사본을 변경 한 다음 업데이트 된 복사본을 set으로 넘깁니다.절반이 포함 된 PriceDate 모델 "change" 이벤트에 바인딩 컬렉션이 같은 일을 어떻게 유사을 전달하여 처리 할 수 ​​있습니다 :

initialize: function() { 
    this.attributes.Price.on(
     'all', 
     function(ev, model, opts) { this.trigger(ev, model, opts) }, 
     this 
    ); 
    //... 
} 
당신이 경우에 당신의 자신의 set 구현을 제공 할 것

누군가 set('Price', some_new_object)을 수행 했으므로 전달자를 리 바인드해야합니다.

관련 문제