Sharing a model between views in backbone.js
I am working on a phonegap app using backbone.js. I have the following models:
I then have the following Views
I want the Measure object to be the model for all Views 3 - 6 so that, when anything changes, I can update the main object and save it.
What is happening in the code below is that, upon first render for the codedOptionsPage, the "this.model" is an instance of the Measure model. However, on subsequent calls to render triggered by adding a code to the Measure's code collection, "this.model" is a reference to the prototype, not an instance, so I get an error saying "Object function (){ return parent.apply(this, arguments); } has no method 'toJSON'"
I am pretty sure the code below is not what it should be, as I'm still struggling through this approach, and I'm happy to take general advice, but I'm particularly wondering what is happening to the model.
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;
}
});
Thanks for looking!
这可能不是解决您的问题的方法,但肯定会有一些更改,我会建议您使代码更清晰。
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;
}
});
链接地址: http://www.djcxy.com/p/48320.html
上一篇: 从收藏中移除时从视图中删除项目