【问题标题】:Rails - trigger javascript events from controllersRails - 从控制器触发 javascript 事件
【发布时间】:2011-07-15 09:54:52
【问题描述】:

我正在考虑实现类似以下的内容,并想知道 a) 是否由于某种我没有想到的原因可能是一个非常糟糕的主意,以及 b) 如果不是 - 是否有现有的 gem去做。

基本上,我希望能够将我的 rails 控制器中的 javascript 事件排队,以便在下一次渲染时触发所有排队的事件并将其从队列中删除。有点像 flash 机制,但用于事件。例如:

在我的控制器中:

def create
  if resource.create 
    add_event('resourceCreated', :id => resource.id)
  end
end

在我的应用程序布局中类似于:

%javascript
  - @events.each do |e|
    $(document).trigger(#{e.event_name}, #{e.event_data})

有什么想法吗?

编辑: 这会很有用,例如创建项目时,服务器可以重定向到该项目的编辑表单,或者可以重定向到相关控制器的索引操作。这些页面不知道刚刚创建了一个项目。但是,如果项目创建成功,也许我想做一些事情,比如关闭一个对话框窗口,但如果不是,则让它保持打开状态,或者我可能需要了解它的任何其他可能原因。显然不仅与创建相关,这只是我用来说明问题的示例

编辑:赏金给任何人以一种或另一种方式令人信服地说服我这是一个好/坏主意或提供更好的选择

【问题讨论】:

  • 除了资源创建/更新/删除还有其他事件类型吗?如果不是,为什么标准的 Flash 消息不适合?

标签: javascript jquery ruby-on-rails events


【解决方案1】:

我明白你想要做什么,但你需要小心分开。

在这种情况下我会做的是创建一个哈希,然后在您的视图中创建#to_json。假设在您的操作底部

控制器

@events = [
   { :type => "item_created", :message => "Woohoo! Item was created"}
]

index.html.erb

<div>Your usual stuff goes here</div>
<script type="text/javascript" charset="utf-8">
  var events = <%= raw @events.to_json %> // You must make sure it's properly sanitised
</script>

jQuery

$.ready(function() { 
   events.each(function () {
      // ... Do what you need to with this
   });
});

【讨论】:

    【解决方案2】:

    我建议使用 Rails 的闪存消息机制来执行此操作,该机制已经存在的目的正是为了让用户知道自上次请求以来发生的任何服务器端事件。将隐藏的机器可解析描述块粘贴到每条 flash 消息的末尾,编写一个 Ruby API 以便轻松添加此类块,然后在您的视图中(或者可能用 JS 编写)根据需要检索和处理它们.

    作为奖励,您还可以在同一个动作中直接告诉用户服务器端事件,即使他们没有在浏览器中启用或提供 JS。

    【讨论】:

      【解决方案3】:

      这是你可以做的......

      将用户发送到带有给定主题标签的页面

      = link_to "Get aWesome!", awesomem_page_path + '#initiate_awesome' 
      

      映射到:

      /path/tosomething#initiate_awesome
      

      在该页面中,加载文档后,放入 na 行以检查页面标签,并根据该标签执行 js evven。这里显示了带有 Haml 并使用 Jquery 事件的 Jquery 示例:

      %h1  aWesomeness is about to happen...
      
      - content_for :jquery do
        :javascript
          $(document).ready(function(){
            if (document.location.hash === "#initiate_awesome"){
              $('#amazing_div').trigger('awesome_event');
            } else {
                  $('#not_so_cool_div').trigger('ultimate_letdown');
            }
           });
      

      通过此设置,一旦页面加载,它将触发您的 js 事件并执行您想要的操作。 aWesomeness获得。

      对于加分,由于此 js 代码在您的模板中,您可以通过控制器从 ruby​​ 渲染 js sn-p 中的事件名称,并将事件链写入 js 以供进一步解析。

      【讨论】:

      • 这似乎是一个可行的替代方案,但要冗长得多。您能否就为什么它比我提出的解决方案更可取提出一些想法?谢谢!
      • 你必须根据你的情况来判断..它不一定更可取..它们实际上非常相似..主要区别在于我使用主题标签并且完全是客户端。独立于您使用的后端。您的主要依赖于控制器。除此之外,我没有看到更多......在那之后,它是你的电话
      • 请记住,你不需要我放在那里的大部分肉鸡。它只是为了完整性
      • 当然,还有几点是它对现有的标签做出了一些假设,尽管它们可以通过传递参数而不是直接覆盖它来解决。此外,它依赖于重定向,而不是渲染,并且需要一些额外的工作才能在一个请求/响应周期中对多个事件进行排队。所有可以解决的小问题
      【解决方案4】:

      您好,您可以通过以下方式从您的控制器触发 js 事件。

      def create
        if resource.create 
          add_event('resourceCreated', :id => resource.id)
        end
          render :update do |page|
            page << "dismiss()"
          end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-20
        • 2019-06-20
        • 2017-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-30
        • 1970-01-01
        相关资源
        最近更新 更多