现实世界中基于 backbone.js 的许多框架的优缺点是什么?

希望有人能够分享一些最新出现的 backbone.js 变体的经验。 我在几个项目中对主干/下划线/需求有一些很好的经验,并且我希望下一步能够针对复杂的应用程序结构采用更高级的解决方案。

我知道有以下框架:

也许我错过了一些。

这里有一个关于差异的简短介绍:

我想知道是否有人可以用这些框架来分享他们在实际应用中的经验。

选择其中一个有什么好处?什么时候提线木偶会比卓别林更好,或者为什么 vetebrae 更适合某些应用,例如。

当然,显而易见的答案是“ 使用最适合你需要的东西”,但我缺乏使用这些框架的经验,无法了解它们的优势/用途/优势或首选场景。

谢谢!

编辑1: 发现这个帖子: 骨干,木偶 VS 骨干-样板

编辑2: 作者: Mathias Schafer (卓别林):

简而言之,目前的结构接近1.0版,因为它已经在生产中使用。在1.0之前,我们不打算添加大的新特性或者打破 API 的变化。

毫无疑问,牵线木偶是最全面、最稳定的图书馆。它解决了使用 Backbone 开发 JS 应用程序的几个方面。例如,它有一个强大的视图层,主干本身离开完全空白。当然,您会发现有些方面不能满足您的需求,您可能觉得需要围绕木偶建立一个结构。

相比之下,卓别林关注的是 Backbone 应用程序的一个非常小但非常重要的方面,即整个应用程序结构和模块生命周期。在这方面,卓别林非常固执己见,更像是一个框架而不是一个库(就像“你的代码调用一个库,一个框架调用你的代码”)。卓别林提供了一些中心类,它们位于单个应用程序模块之上,控制整个应用程序状态。这给了你的应用一个传统的结构,比如 RubyonRails。

在 Chaplin 中,声明一些映射到控制器的路由,一旦路由匹配,Chaplin 就启动控制器。它还处理旧控制器的处理,以及显示和隐藏控制器应该创建的主视图。这是基本的想法,但卓别林照顾丑陋的细节,使这个运行顺利。

这种结构有两个原则: - 模块化、解耦和沙箱 - 使用发布/订阅和中介进行跨模块通信

当然,这些模式在软件开发领域并不新鲜,Chaplin 也不是唯一一个将它们应用于 Backbone.js 应用程序的库。

卓别林还为视图层提供了增强功能,例如一个高度复杂的 CollectionView,但总的来说没有木偶及其区域和布局那么多。但是使用 Chaplin 视图提供的方法编写这样的元类相对容易。

21941 次浏览

我目前正在使用带有布局管理器模块和把手的主干作为模板引擎,我发现使用已经存在的 Grails 后端设置一个小应用程序非常容易。在开始使用布局管理器之前,我读到了木偶和卓别林的故事,它们在我看来都很强大,但也很复杂。然后我想起了最初选择 backbone.js 的原因: 简单性。所有这些框架都在添加被设计遗漏的主干。我并不是说框架不好,但如果我需要更复杂的东西,我会尝试其他项目,比如 ember.js 或 spoutcore,因为它们有一个独特的代码库,在开发人员的头脑中有一个目标。这里,我们在另一个框架之上添加了框架。当然,主干不仅是构建应用程序的主干,也是编写更强大的库的主干,但我认为它唯一真正差劲的地方是视图层,因为它缺少布局管理器和嵌套视图的可能性。与布局经理的差距是填补相当不错。

因此,我对您的问题的回答是: 从现在使用主干开始,问问自己缺少了什么,以及您对框架的期望是什么。如果您发现主干部分遗漏了太多内容,那么可以在其他框架中搜索这些内容,并选择最接近您需要的框架。如果你仍然对这个选择没有信心,也许主干网不适合你,你必须寻找其他的解决方案(ember.js,sproutcore,ExtJs,JavaScript MVC 都很好)。如果您有编写客户端应用程序的经验,那么您并不真的需要所有框架方面的经验来选择正确的框架(当然,这是为您准备的)

我研究了用 Backbone.js 构建的各种框架,并为 HauteLook 的一个项目构建了 Vertebrae。项目目标包括... 动态脚本加载,AMD 模块格式,依赖管理,使用大多数开源库构建,在包中组织代码,优化和构建一个或多个单页面应用程序,主机在完全缓存的服务器上,例如没有服务器端脚本只使用 API 的数据,对我来说最有趣的是,使用行为驱动的项目开发。有一个关于该项目的说明: http://www.hautelooktech.com/2012/05/24/vertebrae-front-end-framework-built-with-backbone-js-and-requirejs-using-amd/

我们的问题:

选定的库(jQuery,Underscore.js,Backbone.js,RequreJS,Mustache)提供模块加载,依赖管理,应用结构(用于模型,集合,视图和路由) ,与 API 的异步交互,各种实用程序和对象来管理异步行为,例如(承诺)延迟,回调。完成框架所需的其余逻辑包括:

  • 管理单页应用状态的对象(模型) ;
  • 展示、安排/过渡和清晰视图的布局经理,以及
  • 响应路由、获取/设置应用程序状态并将工作移交给布局管理器的控制器。

我们的解决方案 (在 Vertebrae 中实现) :

应用程序状态管理器 -

应用程序管理器将数据存储在内存中,并在浏览器存储中持久化数据,以便为公共数据/元数据提供资源。还提供数据(状态) ,以根据以前的交互(例如,选择的选项卡,应用的过滤器)重建页面视图。应用程序状态管理器为资源提供检索状态的策略。意味着充当状态机。

布局管理器 -

布局管理器对每个(呈现的)视图都有一个或多个视图以及文档(DOM)目的地。一个页面可能在多个视图之间转换,因此布局管理器会跟踪视图状态,例如呈现、未呈现、显示、未显示。您可以使用布局管理器来延迟加载和呈现(分离)网站访问者很可能要求的视图,例如页面上的选项卡更改。视图状态之间的转换由此对象管理。可以清除整个布局,以便删除视图对象及其绑定,为垃圾回收(防止内存泄漏)准备这些对象。布局管理器还与控制器通信视图状态。

控制员

控制器对象由路由处理函数调用,负责获取相关状态(应用程序模型)以生成页面(布局)(也负责在路由更改时设置状态)。控制器将请求页面的依赖数据(模型/集合)和构造的视图对象传递给布局管理器。作为一个副作用,控制器的使用可以防止路由对象变得臃肿和混乱。路由应该映射到一个控制器,然后该控制器启动页面视图,保持路由处理函数精简。

Todos 应用程序在开发模式和 Heroku 上都进行了优化。

其他框架中的许多概念都是借用的,例如,需要销毁视图来预览内存泄漏,正如 Derick Bailey-http://lostechies.com/derickbailey/所指出的; 布局管理器,Tim Branyen http://tbranyen.github.com/backbone.layoutmanager/所指出的

总而言之,Backbone.js 只是应用程序中的一个工具。 Backbone.js 库并没有提供构建应用程序所需的所有架构,但确实提供了与 API 的良好交互以及可靠的代码结构,用于... 视图(也像控制器一样)和数据层的模型和集合,最后是路由。我们构建 Vertebrae 来实现我们项目的目标,并决定提取代码作为框架供其他人使用、学习或其他任何东西。

在我看来,你的问题的答案是从所有的框架中学习,并使用你需要的东西来实现你的目标,如果你发现你的项目目标与用 Backbone 构建的框架之一非常吻合,那么很好,否则构建你自己的框架有很多很好的例子被社区分享。或者,如果您发现自己有点迷失在应用程序的方向上,那么选择一些更加固执己见和结构化的东西,比如 Ember.js。最棒的是,有很多种选择可以帮助您使用类似 MVC 的模式和 JavaScript 编写代码。

大部分(全部?)你看到的这些框架解决了同样的问题,但是它们的方式略有不同,目标略有不同。

我认为,公平地说,所有这些项目都将解决这些类别中的问题:

  • 提供合理的默认设置
  • 减少样板代码
  • 在 BackboneJS 构建块的顶部提供应用程序结构
  • 提取作者在应用程序中使用的模式

我从2011年12月开始创建的牵线木偶公司(Marionette)也有一些非常独特的目标和理想:

  • 复合应用程序体系结构
  • 企业消息模式的影响
  • 模块化选项
  • 增量使用(没有全有或全无的要求)
  • 没有服务器锁定
  • 使更改这些默认值变得容易
  • 代码作为配置/覆盖配置

我并不是说其他框架都没有这样的目标。但我认为木偶的独特性来自于这些目标的结合。

复合应用程序体系结构

我花了5年多的时间在使用 WinForms 和 C # 的厚客户端分布式软件系统中工作。我为台式机、笔记本电脑(智能客户端)、移动设备和网络应用程序开发应用程序,它们都共享一个核心功能集,并多次使用同一个服务器后端。在此期间,我学到了模块化的价值,并非常迅速地沿着复合应用程序设计的道路前进。

其基本思想是将应用程序的运行时体验和过程“组合”成许多不一定相互了解的较小的独立部分。它们将自己注册到整个复合应用程序系统中,然后通过各种解耦消息和调用的方式进行通信。

我在我的博客上写了一点关于这个的东西,介绍了 Marionette 作为 Backbone 的一个复合应用程序架构:

消息队列/模式

同样大规模的分布式系统也利用消息队列、企业集成模式(消息传递模式)和服务总线来处理消息。这对我的解耦软件开发方法产生了巨大的影响。我开始从这个角度看待单进程、内存中的 WinForms 应用程序,很快我的服务器端和 Web 应用程序开发就受到了影响。

这直接转化为我如何看待 Backbone 应用程序设计。我在 Marionette 提供了一个事件聚合器,既用于高级 Application 对象,也用于在应用程序中创建的每个模块。

我考虑可以在模块之间发送的消息: 命令消息、事件消息等等。我还认为服务器端通信是具有这些相同模式的消息。有些图案已经进入了牵线木偶,但有些还没有。

模块化

代码的模块化非常重要。创建小型的、封装良好的、具有单一焦点、定义良好的入口和出口点的软件包,对于任何具有重大规模和复杂性的系统来说都是必须的。

牵线木偶直接通过它的 module定义提供模块化。但是我也意识到有些人喜欢 RequreJS 并且想要使用它。因此,我既提供了一个标准构建,也提供了一个兼容 RequreJS 的构建。


MyApp = new Backbone.Marionette.Application();


MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){


// your module code goes here


});

(目前还没有这方面的博客文章)

递增使用

这是我尽可能融入到牵线木偶每个部分的核心理念之一: 使用牵线木偶没有“全有或全无”的要求。

Backbone 本身采用了一种非常增量和模块化的方法来处理它的所有构建块对象。你可以自由选择你想用哪个,什么时候用。我坚信这一原则,并努力确保牵线木偶的工作方式相同。

为了达到这个目的,我在木偶中构建的大多数部件都是独立构建的,与 Backbone 的核心部件一起工作,并且能够更好地协同工作。

例如,几乎每个 Backbone 应用程序都需要在屏幕上的特定位置动态显示 Backbone 视图。应用程序还需要处理关闭旧的视图和清理内存时,一个新的放在适当的地方。这就是木偶 Region发挥作用的时候了。区域处理样板代码,包括获取视图、调用视图上的呈现,以及为您将结果填充到 DOM 中。然后将关闭该视图并为您清理它,前提是您的视图上有一个“ close”方法。


MyApp.addRegions({
someRegion: "#some-div"
});


MyApp.someRegion.show(new MyView());

但是为了使用区域,您不需要使用木偶视图。唯一的要求是从 Backbone 扩展。在对象的原型链中的某一点查看。如果您选择提供 close方法、 onShow方法或其他方法,木偶区域将在正确的时间为您调用它。

没有服务器锁定

我在各种服务器技术之上构建 Backbone/Marionette 应用程序:

  • ASP.NET MVC
  • Ruby on Rails
  • Ruby/Sinatra
  • NodeJS/ExpressJS
  • PHP/Slim
  • 爪哇咖啡
  • 二郎
  • 甚至更多

JavaScript 就是在浏览器中运行的 JavaScript。服务器端的 JavaScript 也很棒,但是它对我如何编写基于浏览器的 JavaScript 没有任何影响。

由于我构建的项目和客户使用的后端技术的多样性,我不能也不会出于任何原因将木偶锁定在单个服务器端技术堆栈中。我不会提供样板项目。我不会提供一个 Ruby gem 或 npm 包。我希望人们明白,木偶并不需要特定的后端服务器。它是基于浏览器的 JavaScript,后端并不重要。

当然,我完全支持其他人为他们的语言和框架提供包。我在 Wiki 中列出了这些软件包,并希望人们在看到需要的时候继续构建更多的软件包。但那是社区的支持,不是牵线木偶的直接支持。

轻松更改默认值

在我努力减少样板代码并提供合理的默认值(这是我直接从 Tim Branyen 的 LayoutManager“借用”的想法)的过程中,我意识到其他开发人员需要使用与我略有不同的实现。

我为模板提供基于内联 <script>标记的呈现,默认情况下使用 Underscore.js 模板。但是您可以通过更改牵线木偶中的 Renderer和/或 TempalteCache对象来替换它。这两个对象提供了渲染功能的核心,wiki 页面显示了如何针对特定的模板引擎和加载模板的不同方式更改这些功能。

有了0.9版的牵线木偶,就更简单了。例如,如果您想用预编译的模板替换内联模板脚本块的使用,您只需要替换渲染器上的一个方法:


Backbone.Marionette.Renderer.render = function(template, data){
return template(data);
};

现在整个应用程序将使用您附加到视图的 template属性的预编译模板。

我甚至提供了一个木偶。V0.9的异步附加组件允许您支持异步呈现视图。我一直努力使它尽可能容易地替换牵线木偶中的默认行为。

代码作为配置

在某些情况下,我是“约定优于配置”的粉丝。这是一个强大的方式来完成的事情,木偶提供了一点这一点-虽然不太多,诚实地说。许多其他的框架——尤其是 LayoutManager ——比木偶提供了更多的约定优于配置。

这是有目的和意图的。

我已经构建了足够多的 JavaScript 插件、框架、附加组件和应用程序,以了解让约定以有意义和快速的方式工作的痛苦。它可以用速度来完成,但通常是以能够改变它为代价的。

为此,我对木偶采用了“代码作为配置”的方法。我没有提供很多“配置”API,在这些 API 中,您可以提供具有静态值的对象文本,这些值可以改变一系列行为。相反,我通过带注释的源代码和实际的 API 文档记录了每个对象所具有的方法,目的是告诉您如何更改 Marionette 以按照您希望的方式工作。

通过为木偶对象提供一个干净清晰的 API,我创建了一种情况,在这种情况下,替换特定对象或木偶作为一个整体的行为是相对简单和非常灵活的。我牺牲了“简单”配置 API 调用,以获得提供自己的代码的灵活性,从而使事情按照您希望的方式运行。

您不会在木偶中找到“ configure”或“ options”API。但是您会发现大量的方法,每个方法都有一个非常具体的用途,具有干净的签名,使得改变木偶的工作方式变得容易。

我在 BenchPrep 工作时开发了 卢卡框架,我们用它在 backbone.js 库上开发了几个大型单页应用程序。

我已经在 ExtJS 工作了几年,并从该框架中窃取了我最喜欢的概念,比如组件驱动架构,在该架构中,您将视图开发为独立组件,然后使用容器视图将它们与其他组件连接在一起。由于它主要基于配置,在 Luca 中开发应用程序感觉很像用 JSON 描述对象。

这种方法的一个优点是可以跨多个应用程序或在应用程序的不同位置重用组件,只需使用 Backbone 的扩展进行一些小的更改。通过对 JSON 配置进行小的调整,可以非常容易地对组件的许多不同布局/表示进行试验。

除了广泛的助手/实用程序功能外,Luca 还提供了许多更高级别的 Backbone 衍生工具,您可以以任何想象得到的方式将它们拼凑在一起,以构建一个复杂的 UI。

视图、组件、容器

  • 增强模型,视图,集合,路由器类
  • 配置选项可以促进模型、集合、视图、应用程序及其各自的管理器之间的通信。
  • 容器(拆分/列布局、网格布局、选项卡视图、卡片/向导视图)
  • 带有所有标准字段组件的 FormView,以及用于与 Backbone 同步的助手
  • GridView,用于从 Luca.Collection 生成可滚动的网格元素
  • CollectionView,用于基于集合生成视图
  • 工具栏/按钮

Bootstrap 样式和免费标记

  • 卢卡非常善于使用 Bootstrap 框架。只要简单地设置 Luca.ableBootstrap = true,并包含 CSS,你的组件(例如标签视图、工具栏、按钮、表单、字段、网格等)就会自动使用 Bootstrap 兼容的标记和 CSS 类约定。
  • 使用 Grid 系统进行布局,并以智能方式响应大多数引导程序基类 css
  • Viewport 和 GridLayout 组件被设置为与引导程序的响应、流体或静态网格系统一起工作。
  • 目的是为 Bootstrap 组件提供一对一的匹配,将它们表示为可配置的主干视图

应用程序组件

  • 骨气。基于模型的状态机提供 getter/setter 方法和属性更改事件作为应用程序控制流的样式
  • 集成控制器组件,它隐藏/显示应用程序页面以响应 Backbone. Router 或 State Machine 事件
  • 集成集合管理器可以跟踪您创建的集合,允许您对它们进行范围界定、分组,并为它们分配默认参数
  • 一个套接字管理器,它是一个在 websocket 服务之上的抽象层,使得推送像 Backbone 一样简单。事件
  • 一个键盘事件路由器,它在组件上触发命名的键事件,这些组件需要响应这些事件

集合和模型增强

  • 集合基于 主干-查询,它提供了一个非常类似 mongoDb 的查询界面
  • 通过简单地设置 colection.localStorage = true 来启用本地存储 Backbone.sync
  • 数据在页面加载时引导的集合的自动填充
  • 缓存方法/计算属性。缓存集合方法的结果,并根据集合或其模型上的更改/添加/删除事件使缓存过期
  • 模型上的计算属性。基于复杂函数构建属性,并根据更改自动更新计算值

活动及挂钩

与普通的 Backbone 组件相比,Luca 组件在发出事件方面更加自由。它们将发出诸如 before: initialize、 after: initialize、 before: render、 after: render、 activation、 first: activation、 deactivation、 first: deactivation 之类的事件,这允许您更精细地调优组件的行为。另外,通过在视图的@hook 属性中定义一个事件,它将自动为您调用一个类似命名的函数(如果存在的话)。这可以防止大量提高可读性的回调样式代码。

您还可以配置 Luca。事件类将事件发布到全局发布/订阅通道,这使得构建大型应用程序更加容易,并有助于模块间通信。

红宝石

Luca 是针对 Rails 和 Sinatra API 开发的,因此目前针对特定堆栈进行了优化,但是它绝不会将您锁定在特定的服务器上。

Luca 作为 RubyGem 的一部分发布,配置为在资产管道上工作,或者作为一个可下载的 JS 文件。

您不需要使用 Rails 或 Sinatra。但如果你这样做,我已经包括了很多有用的东西:

  • 文件。使用 JST 样式变量插值将 luca 扩展作为 HAML 进行处理。(相等于。Jst.ejs.haml)
  • 一个用于浏览器的测试工具,或者基于 Jasmine 的单元测试以及许多 Backbone 和 Underscore 测试助手。
  • Luca 附带的开发工具集的 API 端点(稍后详细介绍)
  • 一个 API 端点,允许您使用 Redis 作为 Luca.Collection 的无模式存储引擎,并使用最少的配置

开发工具

  • Luca 应用程序可以启用带有 Luca 特定帮助器和命令的浏览器咖啡脚本控制台,这些帮助器和命令有助于监视、检查、调试 Luca 应用程序和组件

An example of the Luca in browser Development Console powered by CoffeeScript

  • 在 Rails Gem 和 Luca 基于 CodeMirror 的组件编辑器的帮助下,您可以使用 Coffeescript 直接在浏览器中编辑 Luca Framework 的源代码以及应用程序特定的组件。您将看到响应您的编辑的即时反馈,用更新的原型刷新受影响对象的实例,并且您可以将更改保存到磁盘。

  • 组件测试器是一个实时沙箱,用于独立地处理组成应用程序的组件。它为您提供了修改组件的原型、设置其依赖项和配置组件的工具。每次进行编辑时,组件将立即重新呈现。您可以直接在浏览器中查看和编辑组件生成的标记以及 CSS,并立即查看更改。这使它成为一个非常有价值的实验工具。

  • 组件测试人员将很快与 Jasmine 集成,这样您就可以在编辑代码时实时查看组件单元测试的结果

A screenshot of the component tester

Luca 是一个正在进行中的工作,但是维护了一个稳定的 API (还没有1.0) ,并且已经在几个大型生产应用程序中使用。它肯定是一个非常固执己见的框架,但我正在努力使它更加模块化。我正在积极地编写文档和示例组件。

我是卓别林的合著者,我写了一篇关于卓别林和木偶的深度比较:

Http://9elements.com/io/index.php/comparison-of-marionette-and-chaplin/

这不是一场“枪战”,而是试图以一种平衡的方式解释这两种方法。