2017-07-11 23 views
1

我大多熟悉完整的JavaScript堆棧,自從我一直在Ruby on Rails上工作以來,我從來沒有完全信任我製作XHR請求的方式,因此,我想驗證我的理解。我看了看下面的問題這是在Rails 4中執行AJAX請求的好方法嗎?

,但並沒有完全回答我的問題。

這是根據我的理解發生的事情。在Rails中,我們有我們的MVC,而控制器本質上是我們控制路線將呈現的內容。它也可以被設計爲一個API,用於執行諸如CRUD之類的事情。

接下來,在我們的前端,爲了簡單起見,我們使用jQuery。我們想要發出一個AJAX請求並處理響應。

$.ajax({ 
    url: '/new-sandwich/'+food_id, 
    type: 'post', 
    data: { food_id: food_id} 
}) 
.done(function() { 
    // if it works, refresh the page 
}) 
.fail(function(e) { 
    // if it works alert the user and refresh the page 
    alert(e.responseText) 
    return location.reload(); 
}) 

假設控制器對此非常厚,所以響應需要幾秒鐘。

經過約100行左右...... 然後問題發生在響應。

如果失敗,它會向用戶發出警報,並在刷新後仍然處理,就好像一切正​​常。爲了解決這個問題,我相信我必須在控制器操作的頂部添加更好的驗證。

接下來,問題是,既然這是一個post請求,我不知道在哪裏重定向?如果請求成功,我希望它刷新,但是我是否會從客戶端或服務器執行此操作?如果我不加render :nothing => true在POST控制器動作,我得到的結束......

ActionView::MissingTemplate - Missing template sandwich/create_sandwich, application/create_sandwich 

,但如果我這樣做,那麼有沒有在JavaScript中做這件事的呢?

回答

2

嗯,在我的控制,我通常做線沿線的東西:

class FooController < ApplicationController 

    def create 
    ... do some stuff 
    render partial: 'some_partial', locals: {if: :needed} 
    end 

end 

然後在JavaScript,喜歡的東西:

$.ajax({ 
    url: '/new-sandwich/'+food_id, 
    type: 'post', 
    data: { food_id: food_id} 
}) 
.success(function(data) { 
    $('#someSelector').html(data) 
}) 
.fail(function(e) { 
    // if it works alert the user and refresh the page 
    alert(e.responseText) 
    return location.reload(); 
}) 

因此,控制器返回一些HTML和js將該HTML插入到由$('#someSelector')定義的位置中的頁面中。

如果我的控制器方法確實需要花費大量的時間,然後我通常會做線沿線的東西:

class FooController < ApplicationController 

    def create 
    render json: {job_id: FooCreateService.call(some: params[:thing])}, status: :ok 
    end 

end 

然後我ajax調用可能看起來像:

$.ajax({ 
    url: '/new-sandwich/'+food_id, 
    type: 'post', 
    data: { food_id: food_id} 
}) 
.done(function(data) { 
    @.$jobId = data['job_id'] 
    @showAWorkingOnItNotification() 
    @pollForResults() 
}) 
.fail(function(e) { 
    // if it works alert the user and refresh the page 
    alert(e.responseText) 
    return location.reload(); 
}) 

我的@pollForResults函數將使用@.$jobId輪詢後臺作業服務以完成,然後在作業完成(成功或失敗)時作出適當響應。

它自然比所有這些都複雜一些。但是,這是我通常的方向。