在Marionette中观看窗口级DOM事件的更好结构?

时间:2013-11-08 12:37:01

标签: backbone.js coffeescript marionette

在CompositeView中,我实现了像这样的无限滚动

List.Foo extends Marionette.CompositeView

  initialize: (collection) ->
    @page = 1
    $(window).on('scroll', @loadMore)

  loadMore: =>
    if _nearBottom
      @page++
      App.vent.trigger('list:foo:near_bottom', @page)

  _nearBottom =>
    $(window).scrollTop > $(document).height - $(window.height) - 200

# Then I have the controller to process the event "list:foo:near_bottom", 
# to ask for adding one more page of data in collection.

代码基本上按预期工作。但是我觉得它不能令人满意,因为我认为这个ComposteView会监视其范围之外的一些DOM事件,也就是窗口级DOM事件。

我想使用布局来观看此类事件并进行广播,但我的顶级布局似乎仍然不够宽,无法覆盖窗口/文档:)

我的问题是,在Marionette中观看这类窗口/文档级DOM事件会有什么更好的结构?谢谢!

1 个答案:

答案 0 :(得分:1)

这个问题很长一段时间没有得到解答,我改变了该项目的实施,所以我没有触及它。

Nguyen的评论非常好,并提醒我回顾这个问题。

我也有类似于Nguyen的新观点。

某些东西必须是全球性的,我们无法避免。

这些包括但不限于:

  • 路线
  • 页面滚动
  • 页面加载
  • 窗口调整大小
  • 全球击键
  • ...

Backbone有路由来处理路由事件。其他事情并不那么重要且如此受欢迎,但它们仍需要与路由类似。

在我看来,更好的方法是:在全球范围内观看全球DOM事件,发送不关心任何可能对其感兴趣的App事件。

如果我重新做这个功能,我会做这样的事情(伪代码)

# App
App.on "initialize:after", ->
  @startHistory()
  @navigate('somePath', trigger: true) # Normal steps
  App.module('WindowWatcher').start()

# WindowWatcher module
ExampleProject.module "WindowWatcher", (WindowWatcher, App, Backbone, Marionette, $, _) ->
  class Watcher
    constructor: ->
      @watchPageScroll

    watchPageScroll: ->
      $(window).on('scroll', @_checkScroll)

    _checkScroll: ->
      if @_nearBottom:
        App.vent.trigger(scroll:bottom)

    _nearBottom:
      $(window).scrollTop > $(document).height - $(window.height) - 200

  WindowWatcher.on 'start' ->
    new Watcher()

然后List.Foo控制器会根据需要观看应用事件scroll:bottom,并提供下一页。

可能还有其他部分对此事件感兴趣,例如在“页脚”视图中弹出一个表示您在底部的按钮,或另一个通知,说明您是否想要查看更多需要注册的内容,等等。他们也可以收听由于Marionette的美丽,App Vent无需管理窗口级别的DOM。

重要更新 如果您直接在控制器内部观看应用程序通风口而不是模块级别,请确保控制器将停止侦听此通风口,否则听众将在App.vents中增加,这是内存泄漏。

# FooController
onClose: ->
  App.vent.off 'scroll:bottom'