Backbone.js 向多个主干木偶视图添加UI增强的最佳实践

Backbone.js 向多个主干木偶视图添加UI增强的最佳实践,backbone.js,marionette,Backbone.js,Marionette,因此,对于应用程序中的所有视图来说,在一个元素上执行操作是最好的方式 在非单页应用程序中,您可以运行以下命令: $(document).ready(function() { $('.autosize').autosize(); }); 将autosize函数应用于每个页面上具有autosize类的所有元素 现在,在主干木偶应用程序中,您可以使用onDomRefresh或类似工具在每个视图中执行此操作,但对于影响90%视图的内容,您可能希望它以某种方式自动运行 我不认为有一种方法可以让

因此,对于应用程序中的所有视图来说,在一个元素上执行操作是最好的方式

在非单页应用程序中,您可以运行以下命令:

$(document).ready(function() { 
    $('.autosize').autosize();
});
将autosize函数应用于每个页面上具有autosize类的所有元素

现在,在主干木偶应用程序中,您可以使用
onDomRefresh
或类似工具在每个视图中执行此操作,但对于影响90%视图的内容,您可能希望它以某种方式自动运行

我不认为有一种方法可以让应用程序对象监听所有
onDomRefresh
事件,这可能会解决这个问题。我考虑过重载<代码>木偶程序.MadioRoMoDistRebug 将其添加进去,但它不象是一种主干方法。 我考虑的其他事情是对每个木偶视图进行子分类,以添加用于加载不同UI元素组的混音


我想其他人一定经历过这种情况,所以对使用的方法感兴趣。

只需创建一个基本视图类,并从中继承需要自动调整大小增强的每个视图类

var AutosizeBaseView = Backbone.Marionette.ItemView.extend({
    onDomRefresh: function(){
        this.$('.autosize').autosize();
    }
});
然后让你的课程如下:

var SomeView = AutosizeBaseView.extend({
});

因此,尽管在Twitter上与@julio_menedez和@marionettejs进行了一些有益的聊天,我还是找不到任何真正解决我问题的解决方案。有一个非常好的想法正在使用,但不适合,因为我需要支持旧的IE

因此,我进入了一个危险的猴子修补世界来解决这个问题(请记住,我可能需要用这个工具来熨平一些皱纹,刚刚写完,还没有完全测试过——我会相应地更新)

在Coffeescript中:(底部为javascript版本)

然后要使用它,我只需在我的应用程序对象中设置一个侦听器来捕获我需要的视图事件。e、 g:

@listenTo Marionette.View.EventAggregator, 'view:dom:refresh', (view) ->
  view.$('div').css('backgroundColor', 'red');
因此,在我看来,这是该技术的优点和缺点:

优点:

  • 可以侦听所有视图事件,而无需注入所有视图类或子类化所有视图类
  • 简单易用
  • 对象根本不需要选择使用它
缺点

  • 使用猴子补丁,对木偶API更改造成危险
  • 使用木偶名称空间,因此易受未来木偶名称空间冲突的影响
  • 在视图上下文之外处理视图
  • 拥有一个事件聚合器对象在主干网/木偶网(afaiw)中的其他地方是看不到的,因此打破了一种模式(更新-在主干网.history中可以看到类似的情况)
不管怎样,我欢迎反馈、替代方案、批评:-)并希望这可能对处于同样情况的其他人有所帮助

Javascript:

(function() {
  var event_aggregator, original_view_constructor;

  Marionette.ItemView = Marionette.ItemView.extend({
    constructor: function() {
      return Marionette.View.prototype.constructor.apply(this, Array.prototype.slice.call(arguments, 0));
    }
  });

  original_view_constructor = Marionette.View.prototype.constructor;

  Marionette.View.EventAggregator = event_aggregator = _.extend({}, Backbone.Events);

  Marionette.View.prototype.constructor = function() {
    var _this = this;
    event_aggregator.listenTo(this, 'all', function() {
      var args_array;
      args_array = Array.prototype.slice.call(arguments, 0);
      event_aggregator.trigger.apply(event_aggregator, ['view:' + args_array[0], _this].concat(args_array.slice(1)));
      if (args_array[0] === 'close') {
        return event_aggregator.stopListening(_this);
      }
    });
    return original_view_constructor.apply(this, Array.prototype.slice.call(arguments, 0));
  };

}).call(this);

在《咖啡脚本》中,我认为您还可以:

extend = (obj, mixin) ->
  obj[name] = method for name, method of mixin        
  obj

include = (klass, mixin) ->
  extend klass.prototype, mixin

include Marionette.View,
  onDomRefresh: () -> @$('.autosize').autosize()
它应该涵盖所有视图类型。我没有具体测试过,只是做了一些非常类似的事情,将功能添加到木偶的布局视图中。在处扩展/包括模式。当然,这在直接的JS中也是可行的

更新:

实际上,由于我们可以使用下划线,因此不需要手动定义
include
extend
方法。我们可以说:

_.extend Marionette.View.prototype,
  onDomRefresh: () -> @$('.autosize').autosize()

谢谢你的回答。但我觉得这不对,因为我需要对每个视图类型进行子分类,以覆盖所有视图,并且需要始终从dom刷新事件中发生任何事件的任何子级调用AutosizeBaseView.prototype.onDomRefresh.call(this)。理想情况下,如果我必须对所有视图类型进行子类化,我希望它能够实现,而不必担心调用父方法显示许多增强功能,您运行了吗??我要做的是把它们都放在基类上。$函数将负责只为DOM上存在的元素运行它们,而忽略那些不存在的元素。你不需要在每个视图上自定义onDomRefresh。我们已经有了大约5个,而且我们的应用程序还处于早期阶段。如果我在onDomRefresh事件中连接了其他内容,我需要给家长打电话。谢谢你的分享,很高兴知道我没有错过一些明显的东西看起来不错。别以为能做得更干净,真是太好了!
_.extend Marionette.View.prototype,
  onDomRefresh: () -> @$('.autosize').autosize()