【问题标题】:Using Rails 3.2, Should inclusion of conditional JavaScript in the views be avoided?使用 Rails 3.2,是否应避免在视图中包含条件 JavaScript?
【发布时间】:2012-04-19 15:22:26
【问题描述】:

众所周知,Rails 框架建议通过所谓的 UJS 严格分离 JavaScript 和 Html,但是有时,我发现自己需要在我的视图中包含 JavaScript 的即兴 sn-ps。 首先,我想知道这是否正确?还是不赞成?

我发现自己这样做的最常见情况是,例如,我有一个像这样的条件块:

= form_for @place do |f|
  %h5 Address:
  .input-prepend
    %span{ :class => "add-on" } 
      %i{ :class => "icon-road" }
    = f.text_field :address

  %h5 Name:
  .input-prepend
    %span{ :class => "add-on" } 
      %i{ :class => "icon-pencil" }
    = f.text_field :name

  = f.hidden_field :latitude
  = f.hidden_field :longitude

  #post-button
    %button{ :class => "btn btn-primary", :type => "submit" } Post it! 

- unless logged_in?
  :javascript
    $('#post-button > button, .input-prepend input').addClass('disabled');
    $('.input-prepend input').addClass('disabled');
    $('.input-prepend input').attr('disabled', 'disabled');
    new PopOver().setPopOver($('#post-button > button'), "You must be logged in to register your Business");

看看嵌套在除非条件中的代码,我想知道是否可以把它放在那里,或者我应该以某种方式从控制器生成那部分代码吗? strong>(并将其传递(渲染)给视图:在这种情况下,我不知道该怎么做...)

请让我知道您的想法,我需要知道最有经验的 Rails 开发人员将如何处理这些类型的情况,所以,如果您是其中之一,我很乐意阅读您的回答。

提前致谢!

附言。哦,如果可能的话,请让我看看如何解决这个问题的代码选项,再次感谢!

【问题讨论】:

    标签: javascript ruby-on-rails-3.1 haml ruby-on-rails-3.2


    【解决方案1】:

    UJS 无疑是目前 Rails 世界中最流行的方法,但不同的开发人员将其推向了不同的极端。我认识的一些开发人员完全回避它,因为根据他们的说法,当您仅查看 html 时,您不知道是否会通过 JS 对特定元素进行操作(我个人认为这很好,因为 HTML 只是关于结构,而不是功能)。

    就您的特定问题而言,很明显,您不能简单地将 javascript 放入要加载页面的常规 javascript 文件夹中,因为 javascript 不会知道您是否已登录。您可以放置​​一个指示器DOM 中的某处表明您已登录,但对我来说这太容易被欺骗了。根据服务器上的数据决定是否运行 javascript 的一种相当安全的方法是对服务器进行 AJAX 调用,如下所示:

    1. 浏览器加载的 Javascript 对服务器进行 get AJAX 调用(使用带有 jQ​​uery 的 $.getScript())
    2. Rails 控制器中的操作使用 .js.erb 模板响应 AJAX 调用
    3. 您可以将任意数量的服务器端逻辑放入 .js.erb 模板中(即仅在用户未登录时运行 javascript)

    这样,您可以将 javascript(功能)排除在 html(结构)之外,同时仍然能够做出服务器端决策。在dynamic page caching 的railscast 中有类似的场景

    例如,如果在您的 application.js 中有:

    $.getScript('/users/show')
    

    然后这将调用您的UsersController#show 操作。然后 Rails 会寻找 app/views/users/show.js.erb 模板。在此文件中,您可以拥有以下内容:

    <% unless logged_in? %>
      $('#post-button > button, .input-prepend input').addClass('disabled');
      $('.input-prepend input').addClass('disabled');
      $('.input-prepend input').attr('disabled', 'disabled');
      new PopOver().setPopOver($('#post-button > button'), "You must be logged in to register your Business");
    <% end %>
    

    一旦浏览器收到来自服务器的响应,javascript 就会自动运行。在这种情况下,它只会在用户未登录时运行 javascript。

    【讨论】:

    • 有趣,但让我们看看我是否正确...你是说在 :javascript 中我进行了 $.get Ajax 调用吗?并根据我呈现部分的响应?感谢您的回复。
    • 我会亲自为您的页面创建一个 javascript 文件(如果您使用资产管道,则在 assets/javascripts 中)您将在其中进行 $getScript() 调用。该文件将在您访问该页面时运行。从那里,您可以 a) 让控制器根据特定条件选择要渲染的 .js.erb 文件,或者 b) 拥有一个与上面类似的单个 .js.erb 文件,其中运行的 javascript 会有所不同取决于实例变量、控制器变量等。在我看来,后者更直接。这将使 js 完全脱离您的 HAML。
    • 这听起来很合理,但我想很难将您正在谈论的条件(在这种情况下是否登录)传递给 javascript,对吧?如果可能的话,我想看看一些代码 sn-p。再次感谢贾斯汀。
    • 这就是在来自服务器的 js.erb 响应中制作响应的美妙之处。 js.erb 模板可以像 html.erb 模板一样包含 ruby​​ 代码。当服务器响应 $.getScript() 时,js.erb 模板中包含的任何 javascript 都会在浏览器中自动运行。请注意,由于浏览器通过 JS(而不是 HTML)发出请求,rails 将自动查找要运行的 js.erb 模板。
    • 这是一个了不起的解决方案!我真的不得不说,因为我以前不明白你想做什么。当然,我不知道你可以做这样的包含。这真的很酷。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    相关资源
    最近更新 更多