我的看法, TuneBook
,有型的几个子视图ClosedTune
。 我也有各曲调,独立的全网页浏览OpenTune
。 同样的事件中必然ClosedTune
和OpenTune
,所以我设计我的应用程序,使他们无论从共享“抽象”视图继承Tune
。
为了让我的应用程序更可伸缩的,我想事件的每个ClosedTune
委托给TuneBook
,但对于维护我想同样的处理程序(存储在那些Tune
),以通过使用TuneBook
(虽然他们会显然需要有包裹在一些功能)。
我的问题是,内TuneBook
,找到正确的ClosedTune
调用的处理程序。 什么是建筑师一个很好的方式,还是有对事件委托给父视图其他好的解决办法?
注 -不是重复骨干观的继承与从父扩展事件 (这是关于儿童从父类继承,而我问孩子这是在DOM父的子节点)
在你的父视图(也从延长Backbone.Events
),我会结合onEvent
到DOM事件。 在触发器,它会触发一个事件骨干在内的一些“id”属性,你的孩子知道的意见(大概是一些行标识?)。
var TuneBook = Backbone.View.extend(_.extend({}, Backbone.Events, {
events: {
"click .tune .button": "clickHandler"
},
clickHandler: function (ev) {
this.trigger('buttonClick:' + ev.some_id_attr, ev);
},
}));
那么儿童的意见自然会订阅该关注他们的家长意见活动。 下面我做在initialize
传递父视图以及特殊ID属性您在之前使用options
。
var ClosedTune = Backbone.View.extend({
initialize: function (options) {
options.parent.on('buttonClick:' + options.id, this.handler, this);
},
handler: function (ev) {
...
},
});
你当然也可以建立类似的用户Tune
或OpenTune
。
这里有几种可能性。
1.集中:商店ClosedTune
中的对象TuneBook
实例
店里每一个参考ClosedTune
在tune_book.tunes
。 你如何填充tune_book.tunes
是给你; 既然你提到的加法方法TuneBook
,那就是我如下图所示。
在TuneBook
事件处理程序,检索ClosedTune
从tune_book.tunes
通过使用类似的id
活动对象的属性为关键。 然后调用Tune
或ClosedTune
处理程序。
http://jsfiddle.net/p5QMT/1/
var Tune = Backbone.View.extend({
className: "tune",
click_handler: function (event) {
event.preventDefault();
console.log(this.id + " clicked");
},
render: function () {
this.$el.html(
'<a href="" class="button">' + this.id + '</a>'
);
return this;
}
});
var ClosedTune = Tune.extend({});
var OpenTune = Tune.extend({
events: {
"click .button" : 'click_handler'
}
});
var TuneBook = Backbone.View.extend({
events: {
"click .tune .button" : 'click_handler'
},
click_handler: function (event) {
var tune = this.options.tunes[
$(event.target).closest(".tune").attr('id')
];
tune.click_handler( event );
},
add_tune: function (tune) {
this.options.tunes[tune.id] = tune;
this.$el.append(tune.render().el);
},
render: function () {
$("body").append(this.el);
return this;
}
});
var tune_book = new TuneBook({
tunes: {}
});
[1, 2, 3].forEach(function (number) {
tune_book.add_tune(new ClosedTune({
id: "closed-tune-" + number
}));
});
tune_book.render();
var open_tune = new OpenTune({
id: "open-tune-1"
});
$("body").append(open_tune.render().el);
2.分散:视图对象与使用DOM对象关联jQuery.data()
当你创建一个ClosedTune
,参考存储它,如this.$el.data('view_object', this)
。
在事件侦听器,检索ClosedTune
,如$(event.target).data('view_object')
您可以使用完全相同的处理程序ClosedTune
(在TuneBook
)和OpenTune
,如果你想要的。
http://jsfiddle.net/jQZNF/1/
var Tune = Backbone.View.extend({
className: "tune",
initialize: function (options) {
this.$el.data('view_object', this);
},
click_handler: function (event) {
event.preventDefault();
var tune =
$(event.target).closest(".tune").data('view_object');
console.log(tune.id + " clicked");
},
render: function () {
this.$el.html(
'<a href="" class="button">' + this.id + '</a>'
);
return this;
}
});
var ClosedTune = Tune.extend({
initialize: function (options) {
this.constructor.__super__.initialize.call(this, options);
}
});
var OpenTune = Tune.extend({
events: {
"click .button" : 'click_handler'
}
});
var TuneBook = Backbone.View.extend({
events: {
"click .tune .button": Tune.prototype.click_handler
},
add_tune: function (tune) {
this.$el.append(tune.render().el);
},
render: function () {
$("body").append(this.el);
return this;
}
});
var tune_book = new TuneBook({
tunes: {}
});
[1, 2, 3].forEach(function (number) {
tune_book.add_tune(new ClosedTune({
id: "closed-tune-" + number
}));
});
tune_book.render();
var open_tune = new OpenTune({
id: "open-tune-1"
});
$("body").append(open_tune.render().el);
回应发表评论
我认为选择1,而是针对它决定,因为我已经在tunebook调模型的集合,不希望另一个目标我需要保持同步
我想这取决于什么看家样/同步你觉得需要做的,以及为什么。
(例如,在TuneModel.remove()我将需要删除的意见tunebook的列表视图...大概会需要事件要做到这一点,这样的事件唯一的解决方案开始显得更有吸引力)。
为什么你觉得你“需要删除的意见tunebook的列表视图”? (我并不是说你不应该,只是问你为什么要。)既然你做什么,你是怎么想@ ggozad的做法在这方面有所不同?
这两种技术存储ClosedTune
中的对象TuneBook
实例。 在@ ggozad的技术,它只是隐藏的抽象,或许使得你不太明显落后。
在我的例子它们存储在一个纯JS对象( tune_book.tunes
)。 在@ ggozad的它们存储在_callbacks
通过使用结构Backbone.Events
。
添加ClosedTune
:
1。
this.options.tunes[tune.id] = tune;
2。
this.on('buttonClick:' + tune.id, tune.handler, tune);
如果你想摆脱的ClosedTune
(说你从文档中删除它tune.remove()
和你想要的视图对象完全消失),使用@ ggozad的做法会留下一个孤立的参考ClosedTune
在tune_book._callbacks
除非执行同一种看家的这将使感与我建议的方法:
1。
delete this.options.tunes[tune.id];
tune.remove();
2。
this.off("buttonClick:" + tune.id);
tune.remove();
每个示例的第一行是可选的-这取决于如果你想清理ClosedTune
对象与否。
选项2或多或少是我在做什么的权利,但(由于其他原因),我还存放了模型上查看数据属性。$埃尔,我不禁觉得我们有了一个更好的办法不是存储所有的地方引用。
那么,它最终归结到你的偏好如何构建的东西。 如果你喜欢存储更集中的方式查看对象,你可以将它们存储在TuneBook
实例,而不是使用jQuery.data
。 见#1:集中。
拉上你存储的引用ClosedTune
对象:使用jQuery.data
,或在一个普通的对象TuneBook
,或_callbacks
在TuneBook
。
如果你喜欢@ ggozad的做法对你了解,去为它,但它不是魔术的原因。 因为它是这里介绍我不知道应该由抽象的额外水平相比,更简单的版本我目前在#1提供什么优势。 如果有一定的优势,随时填补我进去。
伟大的解决方案,我已经从其中取出文章 (@戴维-卡德瓦拉德评论)。
扩展一个通用的骨干事件对象并将其存储在一个参考vent
:
var vent = _.extend({}, Backbone.Events);
它传递给父视图:
var parentView = new ParentView({vent: vent});
子视图将触发一个事件:
ChildView = Backbone.View.extend({
initialize: function(options){
this.vent = options.vent;
},
myHandler: function(){
this.vent.trigger("myEvent", this.model);
}
});
与父视图是听孩子的事件:
ParentView = Backbone.View.extend({
initialize: function(options){
this.vent = options.vent;
this.vent.on("myEvent", this.onMyEvent);
let childView = new ChildView({vent: this.vent});
},
onMyEvent: function(){
console.log("Child event has been ");
}
});
免责声明-支付该注意vent
对象必须被注入到每一个视图,以便您将在本文中更好的设计模式,找到利用。