我正在我的第一个骨干应用程序,我发现了一个奇怪的事情,试图附加一个事件。
到目前为止,我得到了这段代码:
//View for @girl, EDIT action
GirlEditView = Backbone.View.extend({
initialize: function(el, attr) {
this.variables = attr;
console.log(attr);
this.render();
},
render: function() {
var template = _.template( $("#girl_edit").html(), this.variables );
$(this.el).html( template );
$("#edit_girl").modal('show');
}
});
//View for @girl
GirlView = Backbone.View.extend({
initialize: function(el, attr) {
this.variables = attr;
this.render();
},
render: function() {
var template = _.template( $("#girl_template").html(), this.variables );
$(this.el).html( $(this.el).html() + template );
},
events: {
"click p.modify": "modify"
},
modify: function() {
//calls to modify view
new GirlEditView({el : $("#edit_girl")}, this.variables);
}
});
//One girl from the list
Girl = Backbone.Model.extend({
initialize: function() {
this.view = new GirlView({el : $("#content")}, this.attributes );
}
});
//all the girls
Girls = Backbone.Collection.extend({
model: Girl,
});
//do magic!
$(document).ready(function() {
//Underscore template modification
_.templateSettings = {
escape : /\{\[([\s\S]+?)\]\}/g,
evaluate : /\{\[([\s\S]+?)\]\}/g,
interpolate : /\{\{([\s\S]+?)\}\}/g
}
//get initial data and fill the index
var list = [];
$.getJSON('girls.json', function(data) {
list = [];
$.each(data, function(key, val) {
list.push( new Girl(val) );
});
var myGirls = new Girls(list);
console.log( myGirls.models);
});
});
如你所见。
我正在使用一个集合来存储所有女孩,而数据来自ruby中的REST api。
每个女孩都会创建一个新的模型实例,并在里面附加一个视图实例。
我不知道这是不是一个好习惯,但我想不出更好的方法。
每个视图都会生成一个具有唯一ID的内容。女孩1女孩-2继续。
现在,模板有一个编辑按钮。 我最初的想法是攻击onclick事件并触发编辑视图以进行渲染。
这是按预期工作的。
到目前为止的问题是:
当事件触发时,所有集合(女孩)都会触发编辑视图,而不是“拥有”渲染视图的那个。
我的问题是我做错了什么?
非常感谢
答案 0 :(得分:4)
所有编辑视图都出现了,因为所有的GirlView都使用相同的el
:
this.view = new GirlView({el : $("#content")}, this.attributes );
然后你渲染添加更多的HTML:
render: function() {
var template = _.template( $("#girl_template").html(), this.variables );
$(this.el).html( $(this.el).html() + template );
}
在视图的el
上使用delegate
绑定了骨干事件。因此,如果多个视图共享相同的el
,您将有多个delegate
附加到相同的DOM元素,并且您的事件将是一团糟的内容。
你有点倒退:模特不拥有观点,观看观看模特和收藏品以及回应他们的活动。你会看到这个right in the documentation:
构造函数/初始化
new View([options])
[...]有几个特殊选项,如果通过,将直接附加到视图:
model
,collection
,[...]
通常,您创建一个集合c
,然后通过将该集合交给该集合来创建该视图:
var v = new View({ collection: c })
或者您创建一个模型m
,然后创建一个包围该模型的视图:
var v = new View({ model: m })
然后视图绑定到集合或模型上的事件,以便它可以在底层数据更改时更新其显示。该视图还充当Backbone中的控制器,并将用户操作转发给模型或集合。
您的初始化应该更像这样:
$.getJSON('girls.json', function(data) {
$.each(data, function(key, val) {
list.push(new Girl(val));
});
var myGirls = new Girls(list);
var v = new GirlsView({ collection: myGirls });
});
然后GirlsView
将遍历该集合并为每个模型创建单独的GirlView
:
var _this = this;
this.collection.each(function(girl) {
var v = new GirlView({ model: girl });
_this.$el.append(v.render().el);
});
然后,GirlView
将呈现如下:
// This could go in initialize() if you're not certain that the
// DOM will be ready when the view is created.
template: _.template($('#girl_template').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON());
return this;
}
结果是每个模型视图都有自己独特的el
来本地化事件。这也使得添加和删除GirlView非常容易,因为所有内容都很好地包含在自己的el
中。