我写了一个简单的程序来创建表单帖子。创建新帖子后,标题将添加到文档中,单击标题后,单击事件将起作用并显示警告。当我创建另一个帖子时,它的标题也会显示第一个帖子的标题,但是当点击时它们都没有弹出警报。
var PostModel = Backbone.Model.extend({
defaults: {
"title": "",
"postTxt":""
}
});
<!-- Collection -->
var PostCollection = Backbone.Collection.extend({
url: '/UserPosts',
model: PostModel
});
<!-- Views -->
var PostModelView = Backbone.View.extend({
model: new PostModel(),
tagName: 'li',
template: _.template($('#post-title').html()),
initialize: function() {
console.log('Initialized PostModelView........');
},
events: {
'click a' : 'showAlert'
},
showAlert: function(){
console.log('event');
alert("You clicked : " + this.model.get('title'));
},
render: function() {
console.log('Running render() of PostModelView.....');
var htmloutput = this.template(this.model.toJSON());
this.$el.html(htmloutput);
return this;
}
});
var postmodelview = new PostModelView();
var postcollection = new PostCollection();
var PostCollectionView = Backbone.View.extend({
collection: postcollection,
tagName: 'ul',
initialize: function() {
console.log('Initialized PostCollectionView .......');
this.collection.on('add', this.render, this);
this.collection.on('remove', this.render, this);
console.log('postcollectionview $el: ' + this.$el.html());
},
render: function() {
this.collection.each(function(postmodel) {
console.log(JSON.stringify(postmodel));
var postmodelview = new PostModelView({model: postmodel});
console.log(JSON.stringify(postmodelview));
//var htmlout = postmodelview.render().$el;
var htmlout = this.$el.append(postmodelview.render().$el);
$('#postcontainer').html('');
$('#postcontainer').append(htmlout);
//this.$el.append(htmlout);
},this);
return this;
}
});
function createPost() {
var postcollectionview = new PostCollectionView();
console.log('running creatPost()');
var postmodel = new PostModel({ title: $('#title').val(), postTxt: $('#postTxt').val() });
postcollection.create(postmodel);
console.log("postcollection: " + JSON.stringify(postcollection.toJSON()));
$('#title').val(''); //clears the input field
$('#postTxt').val(''); // clears the input field
}
答案 0 :(得分:2)
让我们仔细看看:
var htmlout = this.$el.append(postmodelview.render().$el);
$('#postcontainer').html('');
$('#postcontainer').append(htmlout);
与大多数jQuery函数一样, append
返回其接收器,因此htmlout
为this.$el
。这意味着您要反复清除#postcontainer
的内容并将this.$el
重新加入其中。
html('')
做什么?来自fine manual:
当
.html()
用于设置元素的内容时,该元素中的任何内容都将被新内容完全替换。此外,在使用新内容替换这些元素之前,jQuery 会从子元素中删除其他构造(如数据和事件处理程序)。
强调我的。所以每次你:
$('#postcontainer').html('');
您要从#postcontainer
的孩子中删除所有事件处理程序,尤其是您要从this.$el
删除所有事件。
你不应该做以下任何一件事:
$('#postcontainer').html('');
$('#postcontainer').append(htmlout);
该视图应该只是将子视图添加到其el
并让调用者将其el
放在页面的某个位置:
render: function() {
this.collection.each(function(postmodel) {
var postmodelview = new PostModelView({model: postmodel});
this.$el.append(postmodelview.render().$el);
}, this);
return this;
}
然后在来电者中:
var postcollectionview = new PostCollectionView();
//...
#('#postcontainer').append(postcollectionview.render().el);
其他各种问题:
在视图的原型上设置model
属性:
var PostModelView = Backbone.View.extend({
model: new PostModel(),
没有多大意义。视图的每个实例通常都有自己的model
,并且应该在实例化视图时提供。
同样,在视图上设置collection
属性:
var PostCollectionView = Backbone.View.extend({
collection: postcollection,
在实例化视图时,通常会设置collection
:
var v = new PostCollectionView({ collection: post collection });
您在不同的范围内有两个不同的postmodelview
变量,最高级别的变量几乎肯定是错误的。
您在createPost
底部使用labels但标签在该上下文中没有任何意义,我想您的意思是这样说:
$('#title').val(''); // clears the input field
$('#postTxt').val(''); // clears the input field