2011-07-15 51 views
4

我在考慮實現類似以下內容的事情,並希望知道a)如果由於某種原因,我沒有想到可能是一個非常糟糕的主意,並且b)如果沒有 - 有沒有現成的寶石可以做到這一點。Rails - 從控制器觸發JavaScript事件

基本上,我希望能夠從我的rails控制器中排隊javascript事件,以便在下一次渲染時,所有排隊的事件將被觸發並從隊列中移除。而不是像閃光燈機制那樣,而是用於事件。因此,例如爲:

在我的控制器:

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}) 

有什麼想法?

編輯:這將是有用的,例如,當創建項目時,服務器可以重定向到所述項目的編輯表單,或者可以重定向到相關控制器的索引動作。這些頁面不知道某個項目剛剛創建。但是,也許我想做一些事情,如關閉對話窗口,如果該項目已成功創建,但如果它沒有打開,或者任何其他可能的原因,我可能需要知道它。顯然不只是相關的創建,這只是我用來說明問題的例子

編輯:賞金去誰勸我有說服力的一種方式或其他,這是一個好/壞主意或提供更好的選擇

+0

除了資源創建/更新/刪除之外是否還會有其他事件類型?如果沒有,爲什麼標準的Flash消息不適合? – RocketR

回答

4

我明白你想要做什麼,但你需要小心保持分開。

我會在這種情況下做的是創建一個散列,然後#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 
    }); 
}); 
0

這裏是你可以做什麼......

將用戶發送到一個頁面,用givven包括hashtag

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

它映射到:

/path/tosomething#initiate_awesome 

在該頁面中,一旦文件被加載,放在na行檢查頁面主題標籤,並執行一個js evven取決於井號標籤。例如這裏顯示的jQuery與Haml的和使用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代碼片段中呈現事件名稱,並將事件鏈寫入js以供進一步解析。

+0

這似乎是一個可行的替代方案,但是相當詳細。你能否提出一些想法,爲什麼我的建議解決方案更可取?謝謝! – jcoffey

+0

你必須根據你的情況來判斷......它不一定更好......他們實際上非常相似......主要的區別在於我使用井號標籤並且完全是客戶端。獨立於您使用的後端。你的主要依賴於控制器。我沒有看到更多的超越,儘管..在那之後,其呼叫 – noli

+0

記住,你不需要我最擺在那裏..它只是爲了完整性 – noli

2

我會建議使用Rails的flash消息機制來做到這一點,該機制已經存在,目的是讓用戶知道自上次請求後發生的任何服務器端事件。將一個隱藏的機器可解析的描述塊粘貼到每個Flash消息的末尾,編寫一個Ruby API,以便於添加這樣的塊,然後在視圖中(或者用JS編寫)檢索並處理它們。

作爲獎勵,您也可以直接告訴用戶關於同一動作的服務器端事件,即使他們沒有在瀏覽器中啓用JS或可用。

0

嗨,你可以通過以下方式從你的控制器觸發js事件。

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