在开发Backbone应用程序时,我经常发现自己在处理嵌套数据时在视图中实例化模型。以下是一些示例数据:
{
name: Alfred,
age 27,
skills: [
{
name: 'Web development',
level: 'Mediocre'
},
{
name: 'Eating pizza',
level: 'Expert'
]
}
假设我有一些视图PersonView
,它将人物对象PersonModel
作为其模型(其中Alfred将是一个实例)。让我们说我想把这个人的技能渲染为子视图。此时,我创建了一个新视图和一个用于处理嵌套技能数据的新模型。这就是我怀疑我做错了什么,或者至少是一些不理想的事情。
var SkillModel = Backbone.Model.extend();
var SkillView = Backbone.View.extend({
tagName: 'li',
initialize: function() {
this.render();
},
render: function() {
this.$el.html(someTemplate(this.model));
}
});
var PersonView = Backbone.View.extend({
el: ...
initialize: ...
renderSkills: function() {
_.each(this.model.get('skills'), function(skill) {
var skillModel = new SkillModel(skill);
var skillView = new SkillView({ model: skillModel });
self.$el.append(skillView.el);
})
}
});
我真的应该这样做,还是有一些更好的模式,这不涉及第三方库,解决了这个问题?我觉得我并没有以最好的方式将观点和模型脱钩。如果你想要一个具体的问题:这是反模式吗?
答案 0 :(得分:1)
视图用于视图逻辑,数据逻辑模型。
考虑拥有这样的模型:
var SkillModel = Backbone.Model.extend({
});
var SkillsCollection = Backbone.Collection.extend({
model : SkillModel
});
var PersonModel = Backbone.Model.extend({
/*
** Your current model stuff
*/
//new functionality
skills : null,
initialize : function(){
//set a property into the model that stores a collection for the skills
this.skills = new SkillsCollection;
//listen to the model attribute skills to change
this.on('change:skills', this.setSkills);
},
setSkills : function(){
//set the skills of the model into skills collection
this.skills.reset( this.get('skills') );
}
});
所以在你看来renderSkills会是这样的:
var PersonView = Backbone.View.extend({
renderSkills: function() {
//this.model.skills <- collection of skills
_.each(this.model.skills, function(skill) {
var skillView = new SkillView({ model: skillModel });
self.$el.append(skillView.el);
})
}
});
我的伪代码试图适应你的示例代码。但是如果你明白了,基本上你可以在模型中有一个嵌套的模型或集合,所以在视图中没有需要的数据交互/设置,一切都在模型中。我也按你的要求回答,没有第三方处理事情。但是不要介意看看这种插件的来源: https://github.com/afeld/backbone-nested
更新:根据评论,我提供了模型示例的设置:
var m = new PersonModel();
//nested collection is empty
console.log(m.skills.length);
m.set({skills : [{skill1:true}, {skill1:true}]});
//nested collection now contains two children
console.log(m.skills.length);
正如您所看到的,模型用法“始终”只是一组属性,而模型是处理它的模型。您的视图应该使用技能作为视图如何使用任何其他集合。你可以做一个.each迭代,或者更值得听一下这个集合上的添加,重置等事件(但这是本问题范围之外的其他主题)。