【问题标题】:Using backbone with multiple views and little models使用具有多个视图和小模型的主干
【发布时间】:2015-06-17 13:04:31
【问题描述】:

我在大多数项目中都使用主干,我想我确切地知道 M V C 的含义:M 表示数据的抽象,V 表示表示,C 表示处理程序。

但是在我当前的项目中,我发现有很多视图相互交互,而模式很少(与服务器的数据)。

比如我有一个复杂的视图,名字叫V1 V2 V3,当用户在V1中做某事时,V2应该做出相应的反应,V3等也是如此,最后一步可能会请求请求数据从服务器。而且大部分请求都是用来获取数据而不是修改数据。

它不喜欢常见的样式:一个模型的一个(或多个)视图,例如 CRUD 操作。

现在我有两个想法:

1 个虚拟模型

创建一个主干模型来表示整个应用程序的状态,将此模型绑定到所有视图。听起来像是将应用程序作为状态机。

虽然用不同的状态来描述应用程序并不容易。

2 使用事件中介

使用事件中介来注册/取消注册不同的事件,然后视图可以触发或响应不同的事件。

虽然如何定义事件以避免不足或过多,但总之要使事件正交并不容易。或者我还没有找到任何说明。

还有其他替代解决方案吗?

【问题讨论】:

  • interactive with each other 你的意思是把这些视图一起显示并希望它们同时更新吗?

标签: javascript backbone.js


【解决方案1】:

我认为这实际上是一个非常相关的问题。

创建一个主干模型来表示整体的状态 应用程序,将此模型绑定到所有视图。听起来像做 应用程序作为状态机。

如果模型不是对应于特定后端资源的一致表示,这似乎不是一个好主意。
理想情况下,视图是单个模型或集合的表示。当视图绑定到具有不相关属性的模型时,这似乎不太实用,无法在所有情况下进行管理,这也是由于不可预见的未来。

使用事件中介来注册/取消注册不同的事件,然后 视图可以通过不同的事件触发或响应。

我不认为让视图响应自定义事件总体上是一个好主意,但这对我来说是个人的。当应用程序变得更大时,将过多的责任分配给复杂的视图可能会变得一团糟;因此,我将其作为一般规则将视图的任务限制为:

  • 渲染模板;
  • 激活插件(如果它们特定于视图);
  • DOM 事件绑定;
  • (模型绑定);
  • 视图内部的方法(与 DOM 相关);
  • 在与视图交互后需要进一步操作时触发自定义事件以通知其他侦听器;

无论如何,根据我的经验,我发现使用自定义演示者/控制器来实例化/更新自定义事件的视图是很实用的,而且根本不用让视图本身担心这些事情。它使它们保持清洁,您始终知道在那里会找到什么。

您提到的视图 1、2 和 3 可以从演示者重新呈现。
演示者执行以下操作:

“我从服务中获取一些数据并将其提供给我的一些需要的视图 他们。如果有什么变化,我会通知他们”

每个相关视图集通常有 1 位演示者。

我喜欢这种方法,因为:

  • 保持相关视图的逻辑集中;
  • 当一个事件被触发时,presenter 只需要监听一次它控制的所有视图;
  • 演示者被授予相互交谈的权限,我觉得这比所有视图开始相互交谈时更容易控制;

在简单的情况下,所有这些都可能无关紧要。但是在构建更大的应用程序时,我发现它可能会变得一团糟。

我的两分钱

【讨论】:

  • 你的意思是每个视图都应该有一个控制器,而视图只是动作(更新视图,触发事件),控制器会监听其他视图的其他事件并相应地更新视图?跨度>
  • 我不想说你should必须做任何特定的事情;您建议的两种方式最终都会起作用,因为 Javascript 只是一种使事情发生的工具,如果技术上正确,任何事情都会起作用。我的建议是,拥有协调中心可以使流量更易于管理,事实证明在现实生活中也是如此。对我来说,视图是views,因为它们是用户与应用程序交互的大门。任何其他(可重用?)逻辑(包括后端调用)似乎更好地委派给专门用于此任务的组件。
【解决方案2】:

我有一个名为V1 V2 V3的复杂视图,当用户在V1中做某事时,V2应该做出相应的反应,V3等也是如此

您似乎没有 3 个视图,但实际上 1 个视图包含 3 个相互关联的部分。我会使用一个渲染 3 个子视图的超级视图,并监听视图事件。例如:

Backbone.View.extend({
  initialize: function () {
    this.v1 = ...;
    this.v2 = ...;
    this.v3 = ...;

    this.v1.on('user do something', this.v2.respondAccordingly);
    this.v1.on('user do something', this.v3.soDoesEtc);
  }
})

在视图 1 中:

$('button').on('click', function () {
  self.trigger('user do something');
})

【讨论】:

  • 我赞成这种方法。见中见。当视图需要向其内部的视图发出信号以执行某些操作时,外部视图只需调用内部视图上的方法。当视图需要向其上方的视图发出信号时,内部视图会触发外部视图侦听的事件。如果视图需要向“同一级别”的视图发出信号,它会触发一个事件,外部视图接收该事件,然后通过方法调用委托给另一个视图。
【解决方案3】:

这是许多 Backbone 开发人员面临的问题。

我过去所做的是拥有一个 baseModel/baseCollection,并将它们视为其他模型/集合从中扩展的抽象类/接口,恭敬地。这些基础对象将包含一个侦听器/触发器方法,然后我可以在我的应用程序中使用它来更改一个模型/集合,从而能够按照我的选择分别启动集合/模型的更新(从而触发视图更改)。使用这种方法,我可以通过让适当的对象按照我的意愿适当地监听/广播事件来编写我的应用程序。

我的一个朋友创建了一个服务器端 JS 状态机,该状态机将启动超级模型(应用级模型反过来可以触发子视图模型/集合更新)。

当然,Marionette 提供了一个框架,可以减少手动操作,让您可以重新编写应用程序代码。

Backbone.js 的乐趣和负担之一是您拥有所需的所有灵活性。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    相关资源
    最近更新 更多