我正在使用backbone.js开发一个phonegap应用。我有以下型号:
然后我有以下观点
我希望Measure对象成为所有视图3 - 6的模型,这样当有任何变化时,我可以更新主对象并保存它。
以下代码中发生的情况是,首次渲染codedOptionsPage时,“this.model”是Measure模型的一个实例。但是,在随后通过向Measure的代码集添加代码触发渲染时,“this.model”是对原型的引用,而不是实例,因此我收到错误说“Object function(){return parent.apply” (这个,参数);}没有方法'toJSON'“
我很确定下面的代码不是它应该是什么,因为我仍在努力通过这种方法,我很乐意接受一般性的建议,但我特别想知道模型发生了什么。
directory.views.codedOptionsPage = Backbone.View.extend({
events : {
"click a.add-item" :"add"
},
initialize: function () {
this.template = _.template(directory.utils.templateLoader.get('coded-options-page'));
this.model.attributes.codes.bind('add', this.render);
_.bindAll(this, "add");
},
add: function() {
var code = new directory.models.code();
this.model.attributes.codes.add(code);
},
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
this.listView = new directory.views.codedItemListView({el: $('ul.codes', this.el), model: this.model});
this.listView.render();
return this;
}
});
directory.views.codedItemListView = Backbone.View.extend({
el: 'ul.code-list',
initialize: function() {
this.model.bind("reset", this.render, this);
},
render: function(eventName) {
$(this.el).empty();
_.each(this.model.attributes.codes, function(code) {
var li = new directory.views.codedItemView({model: code}).render().el;
$("#code-list").append(li);
}, this);
return this;
}
});
directory.views.codedItemView = Backbone.View.extend({
tagName: "li",
initialize: function() {
this.template = _.template(directory.utils.templateLoader.get('coded-item'));
},
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
感谢您的期待!
答案 0 :(得分:1)
这可能不是您问题的解决方案,但我肯定会建议您更清洁代码。
directory.views.codedOptionsPage = Backbone.View.extend({
events: {
"click a.add-item": "add"
},
initialize: function () {
this.template = _.template(directory.utils.templateLoader.get('coded-options-page'));
// You seem to render the Whole List View when you add a new Code Model
// to the collection .. I think it should be moved to the child View which render the
// code Model
//this.model.attributes.codes.bind('add', this.render);
// Use .get('name') to access the attributes
// Save it to a Variable so that you can pass this in
this.codesCollection = this.model.get('codes');
_.bindAll(this, "add");
},
add: function () {
var code = new directory.models.code();
this.codesCollection.add(code);
},
// Create a new method and move the rendering of listView here
// as it seperated the functionality of the methods
renderListView: function () {
var listView = new directory.views.codedItemListView({
el: $('ul.codes', this.el),
model: this.model,
// Pass in the collection
collection: this.codesCollection
});
listView.render();
},
render: function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
this.renderListView();
return this;
}
});
directory.views.codedItemListView = Backbone.View.extend({
el: 'ul.code-list',
initialize: function () {
// Moved the Add event on collection to this view
// Use listenTo to attach events instead of bind and on
this.listenTo(this.collection, 'add', this.renderCodedItem);
// Replacing this with listen
//this.model.bind("reset", this.render, this);
this.listenTo(this.model, 'reset', this.render);
},
// Moved the rendering of the ItemView to a different method
renderCodedItem: function (code) {
var li = new directory.views.codedItemView({
model: code
});
// Appending the el of the ItemView to code-list
$("#code-list").append(li.el);
// Render the item
li.render();
},
render: function (eventName) {
// Use this.$el to access the el element
//$(this.el).empty();
this.$el.empty();
_.each(this.collection, function (code) {
this.renderCodedItem(code);
}, this);
return this;
}
});
directory.views.codedItemView = Backbone.View.extend({
tagName: "li",
initialize: function () {
this.template = _.template(directory.utils.templateLoader.get('coded-item'));
},
render: function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});