管理具有复杂状态的视图

时间:2012-02-27 19:34:32

标签: javascript model-view-controller backbone.js

我有一个backbone.js应用程序,其视图有多个状态,彼此之间存在很大差异(“视图”,“编辑”等)。每个视图至少有2个不同的模板。还行吧。我的问题是JS视图管理代码。

我依赖于一个初始化 - 瘦 - 渲染 - 厚的方法(我认为这很糟糕),其中渲染方法是80%-90%的逻辑发生的地方。当我想要更改状态时,我只需使用特定参数(“view”,“edit”)调用render方法。在此基础上,视图决定要显示和不显示的内容,要绑定的事件等等。

我认为这很糟糕,因为一方面它会在渲染过程中出现瓶颈,另一方面,它不是正确的状态机,这意味着我没有进行可能已经被绑定的可能回调。当我收到视图时,我只是清理视图就是这样。

我还观察到,我没有使用由骨干提供的委托事件系统,我认为这是另一个减去,因为我认为,它已经很好地实现了(顺便说一下,它是否确保取消绑定回调,当一个删除某些DOM元素?)

我想我需要一些严肃的重构。请帮助提供一些建议,了解多状态Backone视图的最佳方法是什么。

2 个答案:

答案 0 :(得分:2)

我倾向于为这些情况做的是创建一个顶级视图来管理每个州的子视图(索引,显示,编辑等)。当调用用户动作时,例如, “编辑此用户”,“删除此用户”,“保存我的更改”,活动状态视图向路由器发送信号(直接或通过超链接),路由器将告诉顶层视图更新其状态。

继续用户编辑器示例,假设我有一个名为UserEditorView的顶级视图。它为用户编辑器(标题栏等)呈现一个基本容器,然后默认情况下实例化并在该容器内呈现Users.IndexView。

Users.IndexView呈现用户列表。每个用户旁边都有一个编辑图标,它是指向“#users / 555 / edit”的链接。因此,当用户点击它时,该事件将转到路由器,告诉UserEditorView,“嘿,我想编辑用户#555”。然后UserEditorView将删除IndexView(通过调用其.remove()方法),为适当的用户模型实例化Users.EditView,并将EditView放入容器中。

当用户完成编辑用户后,她点击“保存”,然后EditView保存模型。现在我们需要回到IndexView。 EditView调用window.router.navigate('users',{trigger:true}),因此URL得到更新并且路由器被调用。然后路由器在UserEditorView上调用.showIndex(),UserEditorView从EditView交换回IndexView。

答案 1 :(得分:0)

通过一种管理事件卸载的简单方法,我找到了this article on zombie views quite useful

基本上,我没有顶层视图,但我使用视图处理程序渲染所有视图,该处理程序负责处理给定容器的视图。

为了使渲染器更薄,我建议使用路线。它们易于设置,您可以为每条路线提供不同的视图。或者,我以前做的只是拥有不同的模板。使用一般的Backbone.View覆盖:

Backbone.View = Backbone.View.extend({
    initialize: function(attrs) {
      attrs = attrs || {}
      if(!_.isUndefined(attrs.template)) {
        this.template = attrs.template;
      }
    }
});

我注意到我以两种方式重用了视图: 1.编辑视图仅在底层模型和模板上有所不同,但与关联逻辑不同(单击提交验证并保存模型) 2.可以在具有不同模板的几个地方重复使用相同的视图(例如用户列表作为排名或您的帐户)

通过上面的扩展,我可以将{template:'/ my / current / template /}传递给视图,它将按照我想要的方式呈现。与路线一起,我终于获得了灵活,易于理解和精简的设置。