【问题标题】:How can I "deep extend" or "modularly extend" a class in Backbone / Marionette?如何在 Backbone / Marionette 中“深度扩展”或“模块化扩展”一个类?
【发布时间】:2017-04-19 20:51:37
【问题描述】:

在 Marionette 中,我们有一个想要扩展的“主视图”。

var PaginatedDropdown = Marionette.CompositeView.extend({
  template: template,
  events: {
    'click': function () { return 'hello';},
    'keyup': function () { return 'goodbye'}
  },
  childViewOptions: {
     tagName: 'li'
  }
});

理想的用例是通过更具体的视图来扩展这个视图或类,这些视图将实现主类/视图的大部分功能,并修改一些功能:

var MotorcycleColorChooserDropdown = PaginatedDropdown.extend({
    events: {
      'mouseenter': function () { return 'vroom'; };
    }
});

问题是我们不确定如何选择性地修改事件哈希等内容,或覆盖某些子视图选项。具体来说:

  1. 如果MotorcycleColorChooserDropdown 有一个events 对象,它将覆盖PaginatedDropdown 正在侦听的所有事件。我们如何混搭? (允许在MotorcycleColorChooserDropdown 上拥有一个与PaginatedDropdown 的事件对象相结合的事件对象?

  2. 可能无法解决:如果我们想要 PaginatedDropdown click 事件的所有功能,但我们还想在 MotorcycleColorChooserDropdown 中添加一点点呢?我们是否只需要手动将 Parent 中的所有功能粘贴到 Child 类中?

我们考虑过根本不做这样的扩展视图,或者做像MotorcycleColorChooserDropdown = PaginatedDropdown.extend(); 这样的事情,然后一次做一个MotorcycleColorChooserDropdown.events = PaginatedDropdown.events.extend({...});,但这看起来很混乱,丑陋,我相信有更好的方法。

【问题讨论】:

标签: javascript class backbone.js marionette


【解决方案1】:

这就是我一直在做的事情

var PaginatedDropdown = Marionette.CompositeView.extend({
  template: template,
  events: {
    'click': 'onClick',
    'keyup': function () { return 'goodbye'}
  },
  onClick:function(e){
      return 'hello'
  },
  childViewOptions: {
     tagName: 'li'
  }
});

var MotorcycleColorChooserDropdown = PaginatedDropdown.extend({
    events: _.extend({
      'click': 'onClick',
      'mouseenter': function () { return 'vroom'; };
    },PaginatedDropdown.prototype.events),
    onClick:function(e){
        PaginatedDropdown.prototype.onClick.call(this,e)
        //code
    }
});

对于您的第一个问题,我只是将子 events 与父 events 扩展。

至于第二个,我只是从子调用父方法,传入子上下文和事件对象。

它非常冗长,但也非常明确。阅读您的代码的人会确切地知道发生了什么。

【讨论】:

  • 你是对的,除了不存在的...events.extend({...});extend 函数来自 Backbone,并不适用于每个对象。
  • 你说得对,我查看了代码的意图而不是其正确性,将编辑我的答案。
【解决方案2】:

你可以:

var PaginatedDropdown = Marionette.CompositeView.extend({
   template: template,
   childViewOptions: {
     tagName: 'li'
   },
   "events": function() {
     'click': 'onClick',
     'keyup': 'onKeyUp'
   },
   "onClick": function() {
      return 'hello';
   },
   "onKeyUp": function() {
      return 'hello';
   },
}); 

var MotorcycleColorChooserDropdown = PaginatedDropdown.extend({
    "events" : function() {
      //Question: 
      //Basically extending the first events by using the marionette event function and extending it.
      var parentEvents = PaginatedDropdown.prototype.events,
          events = _.extend({}, parentEvents);

      events['mouseenter'] = this.onMouseEnter;
      //add all of the events of the child
      return events;
    }
    "onMouseEnter": function() {
      return 'vroom';
    },
    "onClick": function() {
       //Question 2: 
       //Applying the parent's method
       PaginatedDropdown.prototype.onClick.apply(this, arguments);

       //and adding new code here
   }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多