【问题标题】:Backbone.js with Rails带有 Rails 的 Backbone.js
【发布时间】:2011-03-06 18:50:33
【问题描述】:

我目前正在尝试使用 Backbone.js 和 Rails 应用程序。我的问题是,我不知道如何使用我的 rails 应用程序实现 Backbone 控制器和视图。我已经阅读了很多教程,但它们总是只在backbone.js 中使用一个控制器。

例如,我在 rails 中有两个控制器。

  • 活动控制器
    • 包括两个视图,一个谷歌地图和一个搜索字段。谷歌地图插入了主干视图,搜索字段采用 HTML 格式,并通过主干视图获取其功能。
    • 搜索字段应该从我的 rails 模型中获取数据并在地图内显示标记。

另一个是

  • 用户控制器
    • 这里查看了用户个人资料,我想添加一些 ajax 功能,例如更新值和其他内容

在我的 application.js 中,我使用启动应用程序

var App = {
  Views: {},
  Controllers: {},
  Collections: {},
  init: function() {
      new App.Controllers.Activities();
      new App.Controllers.Users();
      Backbone.history.start();
  }
};

$(function() {
  App.init();
});

问题是,我不需要我的用户配置文件中的活动控制器和 Rails 活动控制器中的用户控制器。我怎么能解决这个问题?我是否应该尝试在 javascript 中读取当前 URL,然后决定使用哪个控制器? 还是我应该把 JavaScript 文件放到 application.html.erb 中,然后在这里决定应该使用哪个控制器?

或者这是使用backbone.js控制器的错误方式?

我对backbone.js 的结构有什么误解吗?还是我以错误的方式使用控制器?

另一个问题是,如何通过 Backbone.js 添加少量 JavaScript,尤其是 jQuery 功能?例如,当用户单击该字段时,我想删除字段内的标签。或者我想做一些选项卡功能,只是切换某些元素的可见性。 我应该为每个使用 javascript 的元素创建一个 Backbone 视图吗?或者这是过载?

希望我说清楚了,任何人都可以提供帮助, 谢谢!

【问题讨论】:

    标签: ruby-on-rails backbone.js


    【解决方案1】:

    为什么不利用 Backbone 提供的路由特性来决定调用哪个方法呢?活动控制器将仅包含用于活动的路由,用户控制器仅用于用户处理,等等。 像这样,您可以像您一样实例化控制器,并且路由将根据当前位置的哈希决定发生什么。

    如果您不能使用带有哈希的链接(或者您的页面上没有此类链接),我只需将视图容器命名为足够具体的名称,以便在需要时仅为当前视图附加事件。

    jQuery 插件等属于 IMO 视图。您的选项卡和输入提示切换也是如此。

    更新

    在一般层面上(我不一定建议这样做):如果您有两种方法:

    // should be only called for the 'Foo' controller
    function foo() {
      alert("FOO");
    };
    
    // should be only called for the 'Bar' controller
    function bar() {
      alert("BAR");
    };
    

    如果想根据当前的 Rails 控制器只调用其中一个,请创建一个小助手:

    例如在你里面 *helpers/application_helper.rb*

    def body_class
      controller.controller_name
    end
    

    然后在您的布局文件(或部分标题)中调用此方法:

    <body class="<%= body_class %>">
    …
    

    并使用例如jQuery 来“拆分”你的 JS 执行:

    if ($('body').hasClass('foo')) {
      foo();
    } else if ($('body').hasClass('bar')) {
      bar();
    } 
    

    【讨论】:

    • 使用路线是个好主意!但正如你所说,我的网址中没有哈希。我正在使用标准的铁路路线。有没有更好的方法来决定选择哪个控制器?或者也许我会分叉主干.js 并添加这个功能。你怎么看?
    • 我认为不需要叉子。您的控制器只是类,除非您调用这些类的方法之一,否则不会真正发生任何事情。你能解释一下你在你的控制器中做了什么让你想以这种方式“拆分”代码吗? (在更一般的层面上:我将根据当前的 Rails 控制器添加另一种调用 JS 的方法。)
    • 感谢您的评论和更新。但我不喜欢 CSS 参与决定应该使用哪个控制器的这种方法。我想以这种方式拆分这段代码,因为我认为将活动控制器的 JavaScript 代码与其他控制器分开会更清晰。例如,我在活动控制器和用户控制器中有一个地图。观点相同,但行为不同。另一件事是,我如何在特定的 rails 方法中处理这个问题(假设代码只属于控制器的方法,例如新操作)?
    • 我不确定我是否可以完全跟随你,但如果行为不同,那么视图就不可能是同一个 IMO。由于行为是视图行为,它属于视图。我想我可能不得不放弃 Backbone Controller == Rails Controller 的想法。我认为您不能将相同的逻辑应用于两种环境。
    • Backbone.Collection = Rails 控制器(以一种安静的方式)。骨干控制器用于控制客户端的流量。一个主干控制器实际上可以根据加载的数据作用于许多不同的轨道控制器。我认为在您的情况下,您不想构建单页应用程序,而是要在页面内使用主干处理动态行为。
    【解决方案2】:

    我个人使用 jammit(来自骨干网的同一作者)。您可以按模块对样式表和 javascripts 文件进行分组,并在不同的页面上使用它们。因此,您为活动视图创建一个模块,为用户视图创建另一个模块,每个都需要必要的 JavaScript 文件。关于此的两件好事:

    • 您只有在页面上加载的页面上使用的代码
    • jammit 为您压缩一切

    在不创建依赖 # 个路由从一个控制器导航到另一个控制器的单页 Web 应用程序时,这是要走的路。在您的情况下,您在主 Rails 应用程序中有多个单页应用程序。

    【讨论】:

    • Jammit 可能是一个很好的方法。但我想知道是否可能存在性能问题。因为您将每个控制器的 javascript 文件压缩到一个文件中,所以您为每个控制器(甚至每个操作)创建了一个唯一的文件。所以每次你访问一个新页面时,整个 Backbone.js 和(在我的例子中)jQuery 框架都会被加载,因为它包含在一个文件中。我怎么能处理这个?将 Backbone.js 和 jQuery 与 Jammit 分开?但是我不能从一个事实中受益,我只有一个 JS 文件和较少数量的 HTTP 请求。你怎么看?
    • 我有一个带有 jQ​​uery 和主干的 common.js 文件和一个用于一组 rails 视图的 js 文件。那将是 2 个请求,一旦加载(和缓存)common.js 文件,就有 1 个请求。 Jammit 会将文件压缩到将用于生产部署的资产文件夹。在这种环境下没有压缩。
    • 请注意,在 Rails 3.1 中,资产管道功能与 Jammit 所做的一样(对于 JS、CSS),允许跨文件很好地分离功能。对于较小的应用程序,默认行为更好——所有 JS 都被缩小/取消注释/等到一个文件中,然后在浏览器本地缓存。很多应用都可以使用清单选项来确定文件的打包方式和发送时间。
    • 抱歉,错过了我的 5 分钟评论编辑截止日期......我认为 @23tux 在第一条评论(性能)中提出的问题可能不是一个问题,除了非常大的应用程序,假设浏览器缓存已正确完成(压缩的 JS 文件只发送一次)。 Rails 3.1 透明地处理所有这些 :-)
    【解决方案3】:

    我是一个 Backbone.js 新手,所以如果我错了,请有人纠正我,但我认为你对 Backbone 控制器的用途感到困惑。

    Backbone.js 控制器基本上由 hashbang 路由(类似于 Rails 路由)和这些路由调用的操作组成。例如,如果您有一个将在 http://mysite.com/backbone_test 处呈现视图的 rails 路由,并且您有以下主干路由:

    var MyController = Backbone.Controller.extend({
      routes: {
        "foo/:bar":            "myFirstFunction"
      },
      myFirstFunction: function(bar){
        console.log(bar);
      });
    

    然后,如果您转到http://mysite.com/backbone_test#foo/THIS-IS-AMAZING,则执行 MyController.MyFirstFunction 并在 JS 控制台中记录“THIS-IS-AMAZING”。

    除非您直接需要这种与 hashbang 相关的功能,例如通过 url 保存 JavaScript 应用程序的状态(例如:http://my.app.com/#key=value&key=value&ad-infinitum=true),否则建议不要使用 Backbone 控制器。您可以通过模型集合和视图获得您描述的所有功能。

    Controllers 和 Backbone 的好处在于它的模块化和不同的部分可以独立使用。

    我想这个答案的总结是,如果你没有单页 javascript 应用程序,不要使用 Backbone 控制器,而是依靠你的 Rails 控制器。

    【讨论】:

    • 感谢您的评论,但我认为即使您没有单页 javascript 应用程序,您也可以(或应该)在 JavaScript 部分变大时使用 Backbone.js。我希望能够使用 Backbone.js 与我的控制器通信的 RESTful 方式。
    • 我没有说你不应该使用 Backbone.js。事实上,我喜欢 Backbone.js,因为它迫使您构建 Javascript 代码并避免意大利面条式代码陷阱。我所说的是你并不总是需要使用 Backbone.js 控制器,特别是如果你的应用程序中不需要带标签的路由。
    • 呃,对不起,我看错了你的答案。但我明白了,我不需要控制器和许多其他主干提供的东西。现在我正在为我的模块使用 require.js。谢谢你的回答!这是一个非常棒的社区!
    • 没问题。我仍然是 Backbone 和 JS 新手,但我实际上越来越多地使用 Backbone 来构建我的代码并通过事件触发器轻松绑定模型和视图。就像我说的,无论控制器如何,Backbone 都很有用。事实上,我认为控制器只是“最近”添加到 Backbone
    猜你喜欢
    • 2012-07-23
    • 2013-01-14
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多