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

时间:2013-02-26 09:40:54

标签: backbone.js marionette

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

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

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

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

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

我希望这是有道理的。

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

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

1 个答案:

答案 0 :(得分:2)

我认为使用Backbone.js非常适合您所描述的此类应用程序。您可能已经阅读过此内容,但大多数骨干文献都围绕您的视图关注服务器生成的JSON模型和集合,然后使用View的渲染功能生成(在客户端上)表示模型/集合的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. View负责实例化模型传递模型所需的相关选项(例如URL)。
  5. 这意味着所有动态服务器端内容都是最终包含在呈现的HTML中,而View是一个模块化的JavaScript组件,它可以为它做些事情,我认为这是你所追求的最终结果。
  6. 所以你提到你想为你的小部件提供AJAX功能,而且这种方法也很好。使用此方法,您现在可以使用fetch模型上的标准Backbone saveWidget函数来获取新内容。在此示例中,它来自从呈现的HTML检索的URL。获得响应后,可以使用视图,渲染功能或其他更精细的函数来根据需要更新页面上的HTML。

    几点:

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

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

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