मेरे पास एक ही मुद्दा था और मैं rycfung के उत्तर में कोड के साथ प्रयोग कर रहा हूं , जो एक महान सुझाव है।
अगर, हालांकि, आप नहीं करना चाहते set
नेस्टेड मॉडल सीधे, या लगातार पास करना चाहते हैं नहीं है {parse: true}
में options
, एक और दृष्टिकोण को फिर से परिभाषित करने के लिए किया जाएगा set
ही।
में रीढ़ 1.0.0 , set
में कहा जाता है constructor
, unset
, clear
, fetch
और save
।
निम्नलिखित मॉडल पर विचार करें , सभी मॉडलों के लिए जिन्हें घोंसले के मॉडल और / या संग्रह की आवश्यकता है।
/** Compound supermodel */
var CompoundModel = Backbone.Model.extend({
/** Override with: key = attribute, value = Model / Collection */
model: {},
/** Override default setter, to create nested models. */
set: function(key, val, options) {
var attrs, prev;
if (key == null) { return this; }
// Handle both `"key", value` and `{key: value}` -style arguments.
if (typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
// Run validation.
if (options) { options.validate = true; }
else { options = { validate: true }; }
// For each `set` attribute, apply the respective nested model.
if (!options.unset) {
for (key in attrs) {
if (key in this.model) {
if (!(attrs[key] instanceof this.model[key])) {
attrs[key] = new this.model[key](attrs[key]);
}
}
}
}
Backbone.Model.prototype.set.call(this, attrs, options);
if (!(attrs = this.changedAttributes())) { return this; }
// Bind new nested models and unbind previous nested models.
for (key in attrs) {
if (key in this.model) {
if (prev = this.previous(key)) {
this._unsetModel(key, prev);
}
if (!options.unset) {
this._setModel(key, attrs[key]);
}
}
}
return this;
},
/** Callback for `set` nested models.
* Receives:
* (String) key: the key on which the model is `set`.
* (Object) model: the `set` nested model.
*/
_setModel: function (key, model) {},
/** Callback for `unset` nested models.
* Receives:
* (String) key: the key on which the model is `unset`.
* (Object) model: the `unset` nested model.
*/
_unsetModel: function (key, model) {}
});
ध्यान दें कि model
, _setModel
और _unsetModel
उद्देश्य पर खाली छोड़ दिया जाता है। अमूर्त के इस स्तर पर आप शायद कॉलबैक के लिए किसी भी उचित कार्यों को परिभाषित नहीं कर सकते हैं। हालाँकि, आप उन्हें उन सबमॉडल्स में ओवरराइड करना चाह सकते हैं जो विस्तार करते हैं CompoundModel
।
उदाहरण के लिए, श्रोताओं को बांधने और change
घटनाओं के प्रचार के लिए वे कॉलबैक उपयोगी हैं ।
उदाहरण:
var Layout = Backbone.Model.extend({});
var Image = CompoundModel.extend({
defaults: function () {
return {
name: "example",
layout: { x: 0, y: 0 }
};
},
/** We need to override this, to define the nested model. */
model: { layout: Layout },
initialize: function () {
_.bindAll(this, "_propagateChange");
},
/** Callback to propagate "change" events. */
_propagateChange: function () {
this.trigger("change:layout", this, this.get("layout"), null);
this.trigger("change", this, null);
},
/** We override this callback to bind the listener.
* This is called when a Layout is set.
*/
_setModel: function (key, model) {
if (key !== "layout") { return false; }
this.listenTo(model, "change", this._propagateChange);
},
/** We override this callback to unbind the listener.
* This is called when a Layout is unset, or overwritten.
*/
_unsetModel: function (key, model) {
if (key !== "layout") { return false; }
this.stopListening();
}
});
इसके साथ, आपके पास स्वचालित नेस्टेड मॉडल निर्माण और ईवेंट प्रचार है। नमूना उपयोग भी प्रदान किया गया है और परीक्षण किया गया है:
function logStringified (obj) {
console.log(JSON.stringify(obj));
}
// Create an image with the default attributes.
// Note that a Layout model is created too,
// since we have a default value for "layout".
var img = new Image();
logStringified(img);
// Log the image everytime a "change" is fired.
img.on("change", logStringified);
// Creates the nested model with the given attributes.
img.set("layout", { x: 100, y: 100 });
// Writing on the layout propagates "change" to the image.
// This makes the image also fire a "change", because of `_propagateChange`.
img.get("layout").set("x", 50);
// You may also set model instances yourself.
img.set("layout", new Layout({ x: 100, y: 100 }));
आउटपुट:
{"name":"example","layout":{"x":0,"y":0}}
{"name":"example","layout":{"x":100,"y":100}}
{"name":"example","layout":{"x":50,"y":100}}
{"name":"example","layout":{"x":100,"y":100}}