Backbonejs,事件聚合和实例化视图

时间:2015-10-05 15:03:22

标签: javascript backbone.js requirejs eventaggregator

TL;博士

Event Aggregator模式在多大程度上重复了Backbone.Router已经做过的事情?如果观看没有相互沟通,即使有事件,也不会更好吗?

麻烦

我在Backbone应用程序中使用Event Aggregrator存在概念性问题。我的基本实现源自Derick Bailey's post about it ..我在Requirejs中使用它,我只是定义了一个扩展Backbone.Events的模块,并在我需要它的模块中需要它。

一些背景知识:我首先要解决的问题是如何最好地处理我应用中视图之间的转换。特别是自动转换。从我的阅读中可以清楚地看出,有两种明显的方法是不鼓励的:

  • 使用类似router.navigate("login", { trigger: true })

  • 的方法在路由器上手动触发导航回调
  • 操纵浏览器window.location.replace("/#login"),从而触发相关的路由回调。

据我所知,对这两种方法的主要反对意见是失去了正确的关注点分离。我当然可以看到避免Views必须彼此了解太多的价值,我寻找更好的方法并找到了事件聚合器。

但是,我在事件聚合器中面临的问题在Derick Bailey的博客文章中非常明显。响应事件的视图已经实例化。任何尚未实例化的视图自然不会响应任何事件。因此,例如,如果我想要一个事件来实例化一个新的View作为某种逻辑的结果,我要么:

  • 在当前视图中实例化一个新实例。在这种情况下,我失去了该方法的大部分优势,因为现在我的视图需要再次了解彼此。

OR

  • 创建某种中央事件处理程序,根据特定事件实例化新视图。 听起来很像我原来的Backbone路由器。看起来我可以将每个路由器回调的逻辑分成不同的控制器,并且我有相同的清晰度。

我的第二个问题可能更为笼统。我觉得Event Aggregator鼓励观点之间的主动互通:诚然,这是一种脱钩的方式。理想情况下,尽管我希望将其保持在最低限度。我真的希望我的用户在定义的区域内执行相当自包含的操作,然后过渡到新区域。我是天真的,希望能够维持下去吗?

我觉得我必须遗漏一些明显的东西,但现在感觉就像Event Aggregator解决了视图间通信的问题(我不确定我想要的),但最终会复制路由器关于View管理。我遇到的问题是我将有两个并行的事件系统。

我真正想要的是使用Event Aggregator处理视图实例化的合理轻量级模式。我知道我可以调查Marionette,但在进入另一个框架之前,我首先要按照我自己的条件理解这一点。

1 个答案:

答案 0 :(得分:1)

哦,骨干,一如既往的困惑。每个人对良好的应用程序应如何运作仍然有不同的意见。

所以这是我的观点。

对于第一个问题,您是否考虑在其中一个模板中使用锚标记?

<a href="/#login">Login</a>

对于第二个问题,我会从其他框架中获取一个页面。在我们公司转离骨干/木偶之前,我们尝试在骨干网上采用通量( redux )架构。它已经很好地适用于一些留在骨干上的应用程序。

采用该架构只是意味着定义一些最佳实践。我认为以下规则适用于

  1. 事件聚合器将是唯一可以直接触发路由更改的内容。
  2. 任何页面至少需要2个级别的视图(或对象)。
  3. 最顶层的观点称为&#34; smart&#34;或&#34;高度耦合&#34;视图(或对象)。它将允许您挂钩到事件聚合器,然后向下传递数据或回调。它们可以表示布局,或者可以基本上没有样式,只是将事件聚合器回调转换为通用视图可以使用的东西。
  4. 第二级及以下应以分离方式设计。我们可以称他们为&#34; generic&#34;视图,他们可以接受处理程序作为参数。这就是他们与外界沟通的方式。
  5. 这意味着,视图中的API和智能视图需要遵循这些API。
  6. 快速示例:

    function init() {
        // this level is highly coupled, and knows about the events
        // that will occur
        var aggregator = new Backbone.Events();
        aggregator.on('gotoLogin', function() {
            router.navigate("login", { trigger: true });
        })
    
        function gotoLogin() {
            aggregator.trigger('gotoLogin');
        }
    
        // the Todo class is generic, and defines an API that expects
        // a gotoLogin callback
        new Todo({
            el: '.js-todo',
            gotoLogin: gotoLogin,
        });
        // the Header class is generic, and it also expects 
        // some way to navigate to the login screen.
        new Header({
            el: '.js-header',
            gotoLogin: gotoLogin,
        });
    }
    

    如果您将应用程序构建为某种单页应用程序。这将导致您嵌套视图,这不是世界末日,但它确实变得棘手,但仍然可行。实际上,您可以自动创建子视图(请参阅牵线木偶)。我提出这个问题是因为它似乎与解耦的原始问题有些模糊。我认为骨干网中的嵌套视图问题尤其成问题。

    我相信人们过分强调可重用的代码和解耦。老实说,需要一些耦合。找到可接受的水平很困难。当每个使用骨干的人都有不同的想法时,定义它是非常困难的。我的建议是你和你的团队应该找到一个在骨干领域适合你的系统并坚持下去,否则肯定会出现混乱。