7

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

基本上我拥有/想要的是:

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

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

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

我希望这是有道理的。

Marionette 是否适合在这种情况下用作客户端框架?我之所以问,是因为我不能 100% 确定木偶模块的概念是否就是我在上述场景中描述为小部件的概念。(我在我的问题中提到了 Twitter Flight,因为我相信这会很合适,但它目前太新了,以至于我现在犹豫不决_

我想基本上我要问的是,是否有人在这些方面有一些经验。

4

1 回答 1

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>

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

App.WidgetModel = Backbone.Model.extend({
    intialize: function () {
        this.url = this.options.url;
    }
});

请注意 Widget 接收 URL 作为其构造函数/初始化函数的参数这一事实。这个小部件模型将代表您的许多小部件(当然,您可以采用这种通用方法来处理更复杂的模型并从呈现的 HTML 中提取不同的数据)。那么接下来请教大家的看法。您可能知道,通常在实例化大多数视图时会将模型或集合传递给它们。但是,在这种情况下,您可以在 View 的初始化函数中创建 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

});

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

new App.WidgetView({el: $("#widget")})'

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

整个方法的最终结果是:

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

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

几点:

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

this.model.fetch({
    type: "POST",
    contentType: "text/html"
});

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

于 2013-07-03T07:43:46.103 回答