我需要所有新的MenuItem模型从父系列中获取菜单属性。 这是一个不起作用的基本示例(因为在MenuItem的默认函数中未定义this.collection)
var MenuItem, Menu, menu;
MenuItem = Backbone.Model.extend({
defaults: function() {
return {
menu: this.collection.name
}
},
// Fake Backbone sync
sync: function(method, model, options) {
if(typeof model.cid != 'undefined') {
var cid = model.cid;
model.unset('cid').set({id:cid}, {silent:true});
}
options.success(model);
}
});
Menu = Backbone.Collection.extend({
model: MenuItem,
initialize: function(options) {
this.name = options.name;
}
});
menu = new Menu({name: "footer"});
menu.create({title: "Page", url: "/page"}, {
success: function(model){
console.log(model.get("menu")) // expect to be "footer"
}
})
答案 0 :(得分:1)
我已经设法通过覆盖集合的创建方法来修复它,我仍然不确定这是否是正确的方法。
create: function(attributes, options) {
return Backbone.Collection.prototype.create.call(
this,
_.extend({menu: this.name}, attributes),
options
);
}
答案 1 :(得分:1)
对于新模型的每种可能性:
我发现_prepareModel
无证件集合功能中的挂钩效果很好。
此集合可以原样用于替换默认的Backbone集合。它增加了
onNewModel
功能,它接收新的模型实例和选项 new-model
事件。var Collection = Backbone.Collection.extend({
/**
* Hook into the native _prepareModel to offer a standard hook
* when new models are added to the collection.
*/
_prepareModel: function(model, options) {
model = Collection.__super__._prepareModel.apply(this, arguments);
if (model) {
// call our new custom callback
this.onNewModel(model, options);
// trigger a new custom event
this.trigger('new-model', model, options);
}
return model;
},
// Called when adding a new model to the collection.
onNewModel: _.noop,
});
你自己的收藏可能是:
var Menu = Collection.extend({
model: MenuItem,
initialize: function(models, options) {
this.name = options.name;
}
onNewModel: function(model, options) {
model.set({ menu: model.get('menu') || this.name });
},
});
保证model
是Model
内的Backbone onNewModel
实例。
// The generic collection, put that in a file and include it once in your project.
var Collection = Backbone.Collection.extend({
/**
* Hook into the native _prepareModel to offer a standard hook
* when new models are added to the collection.
*/
_prepareModel: function(model, options) {
model = Collection.__super__._prepareModel.apply(this, arguments);
if (model) {
this.onNewModel(model, options);
this.trigger('new-model', model, options);
}
return model;
},
// Called when adding a new model to the collection.
onNewModel: _.noop,
});
// Extend from the generic collection to make your own.
var Menu = Collection.extend({
initialize: function(models, options) {
this.name = options.name;
},
onNewModel: function(model, options) {
model.set({
menu: model.get('menu') || this.name
});
console.log("onNewModel menu:", model.get('menu'));
},
});
// then use it
var menu = new Menu([
// works with bare objects
{
title: "Page",
url: "/page"
},
// or Model instances
new Backbone.Model({
title: "Other Page"
})
], {
name: "footer" // the collection option
});
// Listen to the custom event if you want
Backbone.listenTo(menu, 'new-model', function(model, options) {
console.log("'new-model' triggered with", model.get('title'));
});
// or other collection methods
menu.add({
title: "Page",
menu: "won't be overriden"
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>