1

我目前正在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);

这使我可以从我创建的任何视图中调用此方法,而不必为每个视图重新定义它。伟大的!

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

(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);

如果您想知道,tap这是我从 Hammer.js 使用的一个事件,因为这是一个移动应用程序。click因此,为了规避 iOS 和 Android 上 300 毫秒的点击事件延迟,当tap事件在某些元素上触发时,我手动触发了一个事件。

现在,所有这些都工作得很好,我觉得有必要详细描述一下,以便可以根据上下文给出答案。

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

events: {
    'tap .section-container p.title':         'quickClick',
    // I don't want to add this to every single view manually
    'tap a': 'quickClick'
}

相反,我没有将它添加到每个视图中,而是将一个事件对象添加到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);

当然,这是行不通的。每次我需要添加仅适用于该视图的事件时,都会覆盖事件对象。顺便说一句,tap a当我的视图没有自己的事件对象时,它确实有效。

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

4

2 回答 2

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);
  },

一种可能的解决方案可能是覆盖 Marionette 的这个(私有!)部分 - 但它可能会在 Marionette 的新版本中发生变化,您必须始终确保一切正常。所以这很糟糕。

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

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

如果这仅对一个“全球”事件有意义是另一个问题。

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

events: _.extend({'tap a': 'quickClick'}, this.my_fancy_events)

并且还定义了 quickClick 方法,然后将此视图用于所有子视图。然后,他们不在“events”中而是在“my_fancy_events”中定义他们的事件。

于 2013-08-15T13:40:38.180 回答
1

在扩展视图时,我偶尔会发现自己需要在“初始化”中添加一些额外的调用以及扩展“事件”属性以包含一些新调用。在我的抽象视图中,我有一个功能:

inheritInit: function(args) { 
  this.constructor.__super__.initialize.apply(this, args);
  this.events = _.extend(this.constructor.__super__.events, this.eventsafter);
},

然后,在扩展视图中,我可以调用

initialize: function(options) {
  this.inheritInit(arguments)
  //..some extra declarations...
}

而且我可以以常规方式使用“事件”属性。

于 2013-10-25T16:13:00.980 回答