2012-02-22 48 views
19

我有,看起来像下面这样的视图结构的骨干应用程序 - 注意,我已经删除的实现,模型,集合等为简洁:如何在Backbone View层次结构中“冒泡”事件?

NewsListView = Backbone.View.extend({ 

    el: $('li#newspane'), 

    // This is what I would like to be able to do 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
    }, 

    render: function() { 
    }, 

    reset: function(){ 
    } 

}); 

FilterView = Backbone.View.extend({ 

    el: $('li.filter'), 

    initialize: function() { 
    }, 

    render: function() { 
    }, 

    toggleFilter: function() { 
    } 

}); 

AllView = Backbone.View.extend({ 

    initialize: function() { 

     this.newsListView = new NewsListView(); 
     this.filterView = new FilterView(); 

    } 

}); 

从本质上讲,只要FilterViewtoggleFilter()功能被称为,我想发起一个叫做filtered的事件或类似的事件,然后被NewsListView抓到,然后它调用它的reset()函数。如果没有将NewsListView对象的参考传递给我的FilterView,我不确定如何将其发送给它。有任何想法吗?

回答

0

所以,我想出了一个解决方案 - 创建一个对象,扩展Backbone.Events,并将其作为参数传递给多个视图。这几乎就像是演员之间的消息传递,或者什么。无论如何 - 我发布这个作为一个答案,以防其他人需要快速解决方案,但我不会接受答案。这感觉哈克。我仍然希望看到更好的解决方案。

NewsListView = Backbone.View.extend({ 
    el: $('li#newspane'), 

    // Too bad this doesn't work, it'd be really convenient 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
     // but at least this does 
     this.options.eventProxy.bind('filtered', this.reset); 
    }, 
    render: function() {}, 
    reset: function() {} 
}); 

FilterView = Backbone.View.extend({ 
    el: $('li.filter'), 

    initialize: function() {}, 
    render: function() {}, 
    toggleFilter: function() { 
     this.options.eventProxy.trigger('filtered'); 
    } 
}); 

AllView = Backbone.View.extend({ 
    initialize: function() { 
     var eventProxy = {}; 
     _.extend(eventProxy, Backbone.Events); 
     this.newsListView = new NewsListView({eventProxy: eventProxy}); 
     this.filterView = new FilterView({eventProxy: eventProxy}); 
    } 
}); 
0

这个问题可以通过使用small backbone.js破解来解决。只需修改Backbone.Events.trigger传递事件到this.parent

if this.parent != null 
3

你可能会能够使用jQuery事件和骨干事件属性的已有功能来完成此操作。

例如,而不是从你的子视图里面做这样的:这是一个父母,祖父母,等你的孩子视图的任何视图

this.$el.trigger("yourevent", this); 

然后:

this.trigger("yourevent", this); 

做到这一点,而不是,通过在该视图的事件对象上定义属性来收听该视图的$ el上的事件:

events:{ 
    "yourevent":"yourhandler" 
} 

并定义该视图处理程序以及:

yourhandler:function(subview) { 
} 

于是就这样,一个视图并不需要了解存在哪些后裔的观点,唯一事件是有意的类型,如果视图始发事件被破坏,祖先观点没有什么需要改变。如果祖先视图被破坏,骨干将自动分离处理程序。

警告:我还没有真正尝试过这一点,所以在那里可能有一个问题。

+0

这不适合我。 – anyaelise 2015-11-17 17:00:14

+0

谢谢你的aha!时刻。 – 2016-02-24 23:29:32

0

我发现触发和监听事件的最简单方法就是使用Backbone对象本身。它已经在它混合功能的事件,所以你可以触发如:

Backbone.trigger('view:eventname',{extra_thing:whatever, thing2:whatever2}); 

然后,在您的应用程序任何其他骨干视图,您可以侦听此事件如:

Backbone.on('view:eventname', function(passed_obj) { 
    console.log(passed_obj.extra_thing); 
}); 

我不确定在不使用Backbone对象作为您的事件处理程序的优点,而是创建一个单独的对象来执行它,但对于快速和肮脏的工作,上述工作正常。 HTH!

注意:一个缺点是每个听众都会“听到”以这种方式触发的每一个事件。不知道这个大O是什么,但工作要小心,不要用很多这种东西来超载你的观点。再次:这是快速和肮脏的! :)