我认为仅使用 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")})'
通过完成以上所有操作,您几乎可以完成骨干网为您提供的所有其他功能,并且它的模块化和封装得很好,这就是您所追求的。
整个方法的最终结果是:
- 您已将 Widget UI 呈现为纯 HTML(我假设)在没有 JavaScript 的情况下也可以正常工作。
- 您将视图附加到现有 HTML。
- 您将作为选项传递到视图中,内容通过使用 jQuery 从呈现的 HTML 中提取(例如 URL)。
- 视图负责实例化模型,传递模型所需的相关选项(例如 URL)。
- 这意味着所有动态服务器端内容最初都包含在呈现的 HTML 中,并且您的 View 是一个模块化的 JavaScript 组件,可以对其进行处理,我认为这是您所追求的最终结果。
所以您提到您希望为您的小部件提供 AJAX 功能,并且这种方法也很好。使用这种方法,您现在可以使用模型上的标准 Backbonefetch
和save
函数Widget
来获取新内容。在此示例中,它来自从呈现的 HTML 中检索到的 URL。收到响应后,您可以根据需要使用视图、渲染函数或其他更细粒度的函数来更新页面上的 HTML。
几点:
唯一需要注意的是,如果这是服务器提供的内容,您需要将fetch
andsave
函数的内容类型更改为“text/html”。例如:
this.model.fetch({
type: "POST",
contentType: "text/html"
});
最后,我提出的模型是没有内容的实例化。但是,如果您的 ajax 调用是“text/html”的内容类型,您可能需要使用您的模型,以便它可以将此内容正确存储在其属性集合中。有关更多信息,请参阅此答案。