Backbone Marionette模块作为Widgets类似于Twitter Flight

Gee*_*Jan 7 backbone.js marionette

我正在阅读选择正确的客户端框架来分割/模块化Widgets中的前端代码.

基本上我有/想要的是:

  • 一个具有多种页面类型的复杂网站,因此没有单页面应用程序.
  • 所有页面都能够在不使用javascript的情况下呈现完整的页面.IOW:javascript仅用作浓缩.
  • 很多页面都有一种非常动态的方式,可以在屏幕上显示小部件.为了克服服务器端的复杂性,我将我的代码模块化为小部件(复合模式),其中每个小部件都负责它自己的:
    • 服务器端控制器代码
    • 服务器端模板(使用hogan/mustache)
    • 路由端点,是否需要从客户端调用
    • 结构css(css融合小部件的结构而不是外观和感觉)
  • 服务器端RegionManager最终决定呈现哪些小部件以及它们在屏幕上呈现的位置.结果是RegionManager将整个html(服务器生成的)吐出作为所有小部件呈现的组合.

现在,其中一些小部件具有客户端逻辑,需要在客户端上重新呈现.以搜索页面为例,需要能够通过ajax进行更新.(我已经描述了这个过程,它在客户端和服务器上使用DRY模板, 这里)

我最终想要的是,鉴于我已经在服务器上使用了复合模式,以某种方式将其扩展到客户端,以便Widget(屏幕上的1个特定逻辑块)包含所有提到的服务器端代码,以及所有需要的客户端代码.

我希望这是有道理的.

Marionette是否适合在这种情况下用作客户端框架?我问,因为我不能100%确定木偶模块的概念是否是我在上面的场景中描述的Widget.(我在我的问题中提到了Twitter Flight,因为我认为这是合适的,但它目前是如此新,以至于我现在犹豫不决

我认为基本上我要问的是,是否有人在这些方面做了一些经验.

dca*_*son 2

我认为仅使用 Backbone.js 对于您所描述的此类应用程序来说是完美的。您可能已经阅读过本文,但大多数主干文献都集中在具有关联服务器生成的 JSON 模型和集合的视图,然后使用视图的渲染函数(在客户端)生成表示模型/集合的 HTML UI。

然而它没有这种方式使用。事实上,没有什么可以阻止您将视图附加到已包含内容的现有元素,这为您提供了 Backbone 的模块化、事件系统等的所有好处。我经常使用没有模型或集合的视图,纯粹是因为我喜欢风格的一致性。在我必须使用尚未获得或永远不会有良好的 REST API 的较旧的现有应用程序的情况下,我还使用了如下所述的方法,但它们确实提供了 HTML 内容。

首先,假设以下 HTML 代表您的一个小部件:

<div id="widget">
    <div class="widget-title"></div>
    <div class="widget-body">
        <!-- assume lots more html is in here -->
        <a href="/Controller/DoWidgetStuff">Do something!</a>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以将主干与单个Widget模型一起使用。这将是一个非常简单的模型,如下所示:

App.WidgetModel = Backbone.Model.extend({
    intialize: function () {
        this.url = this.options.url;
    }
});
Run Code Online (Sandbox Code Playgroud)

请注意,Widget 接收一个 URL 作为其构造函数/初始化函数的参数。这个小部件模型将代表您的许多小部件(当然,您可以采用这种具有更复杂模型的通用方法,并从呈现的 HTML 中提取不同的数据)。那么接下来谈谈你的看法。您可能知道,通常在实例化大多数视图时会将它们传递给模型或集合。但是在这种情况下,您可以在视图的初始化函数中创建 Widget 模型,并向其传递来自预渲染 HTML 的 URL,如下所示:

App.WidgetView = App.View.ComboboxView = Backbone.View.extend({

    initialize: function () {

        this.model = new App.WidgetModel({}, { url: this.$("a").attr("href") });

    }

    // rest of the view code

});
Run Code Online (Sandbox Code Playgroud)

因此实例化视图将类似于:

new App.WidgetView({el: $("#widget")})'
Run Code Online (Sandbox Code Playgroud)

通过完成上述所有操作,您几乎可以完成骨干网为您提供的所有其他操作,并且其模块化和封装良好,这就是您所追求的。

整个方法的最终结果是:

  1. 您已将 Widget UI 呈现为纯 HTML,(我认为)无需 JavaScript 即可正常工作。
  2. 您将视图附加到现有的 HTML。
  3. 您可以将使用 jQuery 从渲染的 HTML 中提取的内容(例如 URL)作为选项传递到视图中。
  4. 视图负责实例化模型并传递模型所需的相关选项(例如 URL)。
  5. 这意味着所有动态服务器端内容最初都包含在渲染的 HTML 中,并且您的 View 是一个可以对其执行操作的模块化 JavaScript 组件,我认为这就是您所追求的最终结果。

所以您提到您希望为您的小部件提供 AJAX 功能,并且这种方法也很好。使用这种方法,您现在可以使用标准 Backbonefetchsave功能Widget来获取新内容。在此示例中,它来自从呈现的 HTML 中检索的 URL。当您收到响应时,您可以使用视图、渲染函数或其他更细粒度的函数来根据需要更新页面上的 HTML。

几点:

唯一需要注意的是,如果服务器提供的是“text/html”,则您需要将fetch和函数的内容类型更改为“text/html”。save例如:

this.model.fetch({
    type: "POST",
    contentType: "text/html"
});
Run Code Online (Sandbox Code Playgroud)

最后,我提出的模型是实例化的,没有任何内容。但是,如果您的 ajax 调用是“text/html”内容类型,您可能需要使用您的模型,以便它可以将此内容正确存储在其属性集合中。请参阅此答案以获取更多信息。