Rails 3.2 JS-heavy App的设计模式

时间:2012-02-20 10:19:15

标签: ruby-on-rails design-patterns backbone.js

我正在开发一个新的rails 3.2公司管理应用程序,该应用程序严重依赖于JSON数据(自动完成结果,日历事件,任务,动态表单操作等)。后端系统已经非常可靠,因此我们正在投资UI部分,我们希望使其更像webapp,反映其他“胖客户端”应用程序(如Google的应用程序)的行为。为了实现这个目标,最好的设计模式是什么:使用诸如Backbone.js之类的MVC JS框架,从而将大部分数据操作委托给UI并与我们的JSON api接口,或者使用远程JS(即js.erb templates),它允许更多地使用Ruby代码?

我们已经在一些视图中非常粗略地使用Backbone.js,但似乎前一种方法使用了大量的开发人员资源,因为JS更难编码,我们在UI上镜像一些模型代码会有额外的负担,同时对最终用户反应更快。后一种方法允许以牺牲响应时间为代价来获得更精简的View代码,并且总而言之,感觉不太正确,但开发速度更快,更灵活。

请记住,我们是一个拥有大量Rails经验的小团队,而不是JS / Coffeescript / Backbone.js,我们有一个紧密的截止日期,您会选择哪种方法?我之所以处于亏损状态,是因为我们公司对代码的质量和对现代设计模式的坚持感到自豪,所以我不禁想到,尽管它有优点,但使用远程JS感觉就像''糟糕的捷径',所以我真的很感谢你们的意见。也许我只是有偏见。

1 个答案:

答案 0 :(得分:2)

嗯,我无法为你做出决定,这主要取决于截止日期的接近程度,但我个人更喜欢Backbone.js方法。

如果我不得不说我可以说你将拥有一个静态且可缓存的JS脚本和轻量级AJAX请求(仅限JSON),而使用其他方法则会有更重且不可缓存的脚本下载。

但最重要的是,我认为Backbone方式是让代码整理和维护的最佳方法。

  1. Coffeescript非常棒且学得很快。它简化了JS语法并使其变得有趣。值得一试。学到了30多万。

  2. Backbone.js很棒,学习起来很快。使用这种方法可以让你依赖事件,这比我们没有的事情要干净得多。

    由于资源管道,您可以将视图/模型/路由器类拆分为单独的文件,这非常好。

    感谢coffeescript,您可以使用非常简洁的语法编写骨干对象:

    class @MyView extends Backbone.View
      events:
        'click obj': 'handler'
      [...]
    

    有了这个,我在项目中添加了一个@module帮助器来将我的对象组织成命名空间。

  3. 但是,您需要一些时间才能找到合适的文件组织。

    你可以从gem rails-backbone开始,让一些发电机类似于轨道发电机。我不喜欢它个性,但我认为这是一个好的开始。它包括适用于rails的Backbone.sync功能。

    修改

    这里有关于@module助手的一些细节。我在application.js.coffee中添加了此内容(不要忘记require_self):

    @module = (names, fn) ->
      names = names.split '.' if typeof names is 'string'
      space = @[names.shift()] ||= {}
      space.module ||= @module
      if names.length
        space.module names, fn
      else
        fn.call space
    

    在我的班级文件中:

    @module 'MyProject.Model', ->
      class @MyModel extends Backbone.Model
        [...]
    

    (请注意,@this.的coffeescript快捷方式。)

    如果需要,帮助程序会创建对象MyProjectMyProject.Model(如果为null),并使用this绑定到MyProject.Model执行给定的函数。因此,您可以从根命名空间(document)访问您的模型:

    m = new MyProject.Model.MyModel
    

    你也可以给这个帮手涂抹:

    @module 'MyProject', ->
      @module 'Model', ->
        [...]
    

    我使用以下命名空间层次结构

    MyProject
      Model
      View
      Router
      Runtime (to store all runtimes objects and don't pollute the root namespace, easier for debug)