如何将默认事件添加到Marionette的Marionette.View基本类型?

Jar*_*rod 1 marionette

我正在Marionette.View使用我命名的方法扩展Marionette的基本类型quickClick.我这样做

配置/木偶/ view.js

(function() {

    define([
        'backbone.marionette'
    ],

    function(Marionette){

        return _.extend(Backbone.Marionette.View.prototype, {

            quickClick: function(e) {
                $(e.target).get(0).click();
            }

        });

    });

}).call(this);
Run Code Online (Sandbox Code Playgroud)

这允许我从我创建的任何视图中调用此方法,而无需为每个视图重新定义它.大!

这是一个精简的视图,事件对象仍然存在:

(function() {

    define([
        'backbone.marionette',
        'app',
        'templates'
    ],
    function(Marionette, App, templates){

        // Define our Sub Module under App
        var List = App.module("SomeApp");

        List.Lessons = Backbone.Marionette.ItemView.extend({

            events: {
                'tap .section-container p.title':         'quickClick'
            }

        });

        // Return the module
        return List;

    });

}).call(this);
Run Code Online (Sandbox Code Playgroud)

万一你想知道,tap是我在Hammer.js使用的一个事件,因为这是一个移动应用程序.因此,为了规避iOS和Android上的300ms点击事件延迟,我会clicktap事件触发某些元素时手动触发事件.

现在,所有这些工作都很顺利,我觉得有必要对此进行详细描述,以便在上下文中给出答案.

我的问题是必须定义events对象.我完全不介意上面提到的那些元素,.section-container p.title.但是,我想在每个视图中为所有 <a>标签注册一个tap事件.在我创建的每个视图中继续定义此事件没有意义

events: {
    'tap .section-container p.title':         'quickClick',
    // I don't want to add this to every single view manually
    'tap a': 'quickClick'
}
Run Code Online (Sandbox Code Playgroud)

相反,为了将它添加到每个视图,我想我只是将一个事件对象添加到config/marionette/view.js文件中,我在其中添加了一个方法到Marionette.View原型.

这就是我做的

(function() {

    define([
        'backbone.marionette'
    ],

    function(Marionette){

        return _.extend(Backbone.Marionette.View.prototype, {

            events: {
                'tap a': 'quickClick'
            },

            quickClick: function(e) {
                $(e.target).get(0).click();
            }

        });

    });

}).call(this);
Run Code Online (Sandbox Code Playgroud)

当然,这不起作用.每次我需要添加仅适用于该视图的事件时,都会覆盖events对象.顺便说一句,tap a当我的视图没有自己的事件对象时,它会工作.

所以,我的问题是:如何将默认事件添加到Marionette的Marionette.View基本类型?

小智 5

"当然,这不起作用.每次我需要添加仅适用于该视图的事件时,都会覆盖事件对象."

是的,这似乎是个问题.以下是Marionette参与活动授权的部分:

// internal method to delegate DOM events and triggers 
_delegateDOMEvents: function(events){
    events = events || this.events;
    if (_.isFunction(events)){ events = events.call(this); }

    var combinedEvents = {};
    var triggers = this.configureTriggers();
    _.extend(combinedEvents, events, triggers);

    Backbone.View.prototype.delegateEvents.call(this, combinedEvents);
  },
Run Code Online (Sandbox Code Playgroud)

一个可能的解决方案可能是覆盖Marionette的这个(私人!)部分 - 但它可能会在Marionette的新版本中发生变化,你总是必须确保事情仍然有效.所以这很糟糕.

但你可以在你的子视图中做这样的事情:

events: _.extend(this.prototype.events, {
  'tap .section-container p.title': 'quickClick'
})
Run Code Online (Sandbox Code Playgroud)

如果仅对一个"全球"事件有意义则是另一个问题.

或者你可以定义一个抽象的View类,它可以做类似的事情

events: _.extend({'tap a': 'quickClick'}, this.my_fancy_events)
Run Code Online (Sandbox Code Playgroud)

并定义了quickClick方法,然后将此视图用于所有子视图.然后,他们将事件定义为"事件",而不是"my_fancy_events".