0

私はアイデアを使い果たし、解決策のヒントがないままウェブを調べました。私は本当に、本当に立ち往生しているので、誰かが私をこの混乱から抜け出させてくれることを願っています.

私のルートの 1 つは、データベースをクエリし、一連のインスタンス変数 (@campagnes および @missions) を介して erb を介してデータをレンダリングします。心配はいりません。すべて正常に動作します。

ドロップダウン セレクターに基づいてテーブルのデータをフィルター処理するのに役立つ jQuery 関数をセットアップしました。したがって、ユーザーがドロップダウンで選択した値を変更すると、jQuery の $.ajax メソッドがページをリロードし、選択した値を「get」ルートに渡します。

これが私が得られないものです。呼び出しは機能し、成功し、パラメーターがルートに渡され、データベースから読み取るために使用されますが、新しいデータセットを持つすべてのインスタンス変数は、ビューで評価されることを拒否します。代わりに、古いもの (Ajax 呼び出しの前に最初の GET で評価されたもの) がまだ使用されているため、テーブルは古いテーブルのままです。

ビューでインスタンス変数を再度評価するには、Ajax 呼び出しで何を渡す必要がありますか?

これが私のルートです:

get '/admin/mission' do
# load the appropriate js file in template
@js = "mission.js"

# retrieve list of all campagnes, latest on top
@campagnes = Campagne.all :order=>:id.desc


if !params[:campagne]
#puts "camp id retrieved from normal GET"
camp_id = @campagnes[0].id # first campagne in collection is latest
else
#puts "camp id retrieved from ajax call"
camp_id = params[:campagne] # if submitted via Ajax
end

# retrieve list of missions for selected campaign
@missions = Mission.all :campagne_id => camp_id, :order=> :numero.asc

erb :admin_mission , :layout => !request.xhr?

end

私の見解(重要なものまで編集)

<div id="mission_form">
<form class="cmxform" name="mission" action="/admin/mission" method="post">
<ol>
<li>
  <label for="campagne" id="campagne_label" >Choisir une Campagne</label>
  <select id="campagne" name="campagne">
    <% @campagnes.each do |c| %>
      <option value="<%= c.id %>"> <%=h c.nom %> </option>
    <% end %>
  </select>
</li>
<li>
  <label for="numero" id="numero_label" >Num&eacute;ro</label>
  <input type="text" name="numero" id="numero" placeholder="" size="5"/>
  <label class="error" for="numero" id="numero_error">Champ obligatoire.</label>
</li>
<li>
  <label for="nom" id="nom_label" >Nom de la mission</label>
  <input type="text" name="nom" id="nom" placeholder="" size="50"/>
  <label class="error" for="nom" id="nom_error">Champ obligatoire.</label>      
</li>
<li>
  <input type="submit" name="submit" id="submit_btn" class="button" value="Ajouter" />
</li>
</ol>  
</fieldset>
</form>
</div>

<table div="table_mission" id="hor-minimalist-a" summary="Main Table">
  <!-- Table header -->
  <thead>
  <tr>
  <th scope-"col">Campagne</th>
  <th scope="col">Mission</th>
  <th scope="col">Briefing</th>
  <th scope="col">De-Briefing</th>

 </tr>
</thead>

<!-- Table body -->
<tbody>
<% @missions.each do |m| %>
<tr>
  <td>
    <%=h m.campagne.nom %>
  </td>
  <td>
    #<%=h m.numero %>: <%=h m.nom %>
  </td>
  <td>
    <%=h m.briefing %>
  </td>
  <td>
    <%=h m.debriefing %>
  </td>
  <td>
    <span><a href="/<%= m.id %>">[edit]</a></span>  
  </td>
  <td>
    <class="meta"><%= m.created_at.strftime("Created: %m/%d/%Y") %>
  </td>  
</tr>
<% end %>
</tbody>  
</table>

そして私のスクリプトファイル(重要なビットを保持するために編集されています):

$(document).ready (function() {
// hide all error and confirm labels
// refresh  mission table if change campagne dropdown
$('#campagne').change(function() {
  var inputs = [];
  $(':input').each(function () {
        inputs.push(this.name + '=' + escape(this.value));
      });

  $.ajax({
    data: inputs.join('&'),
    url: '/admin/mission', // couldhave used: this.action if it was a submit...
    timeout: 2000,
    error: function() {
      console.log("Failed to submit"); // remove when going live
    },
    success: function() { // 

      $('label#campagne_confirm').show(function() {
            console.log("Sucess!");

          });
       }
 });
});
4

3 に答える 3

1

インスタンス変数は、ERB テンプレートから HTML / JavaScript ビューを作成するためにのみ使用されるため、ページをリロードしなくても、これらの変数の値をいくら変更しても、ビューとして既にレンダリングされているものには影響しません。

Ajax 呼び出しは、JavaScript がページの DOM を操作するために使用できる形式で、ページが必要とする新しいデータを返す必要があります。たとえば、サーバー側で構築された json のナイス ブロックを返します。

また、テーブル データの操作に役立つ優れた jQuery プラグインであるDataTablesも参照してください。いくつかの優れた Ajax ハンドラーがあります。

于 2012-09-04T22:22:34.067 に答える
0

何度も髪を引っ張った後、私はある種の解決策(私はあまり好きではありません)と行動の説明を見つけました(私は100%確実ではありませんが)。

動作に関しては、私のAjax呼び出しはページを更新しません(これは結局のところAjaxの意図された動作です)。これは、新しい値が表示されなかった理由を説明しています。

投稿ルートからリダイレクトするAjax投稿を介して解決策を見つけようとしましたが、どうやらajax投稿は投稿ルートのリダイレクトをキャンセルします(理由はわかりません)。

したがって、最終的には、次のような(醜い)ajaxのみのアプローチを採用しました。

// refresh  mission table if change campagne dropdown
$('select#campagne').change(function() { 
//retrieve value from select tag
var camp_id = $('select#campagne').val();
// pass the parameter in the resource
var uri = "/admin/mission?campagne=" + camp_id;
// GET resource with parameter
// and pass the data returned (the page itself) inside an element
// with some filtering to only get the table from the page
$.get(uri, function(data) {
    console.log("get succesful");
    var $table = $(data).find('tbody');
    console.log($table);
    $('tbody').replaceWith($table);
    });

}); 

これを行うにはもっと良い方法があると確信しています。それが何であるかはわかりません。

于 2012-08-26T20:35:14.493 に答える
0

私の提案は、キャンペーン (キャンペーン?) リスト用に完全に別のルートを持つことです。

def get_campagne_id
  @campagnes = Campagne.all :order=>:id.desc # you might want to cache this
  camp_id = if !params[:campagne] # personally I'd pass the params as arguments, but this will do...
    #puts "camp id retrieved from normal GET"
    @campagnes[0].id # first campagne in collection is latest
  else
    #puts "camp id retrieved from ajax call"
    params[:campagne] # if submitted via Ajax
  end 
end


def mission_by_campaign( camp_id )
  # retrieve list of missions for selected campaign
  Mission.all :campagne_id => camp_id, :order=> :numero.asc
end

これは次のようになります。

get "/missions_by_campaign", :provides => :json do
  content_type :json
  missions = mission_by_campaign( params["camp_id"] )
  missions.to_json
end

get '/admin/mission' do
  # load the appropriate js file in template
  @js = "mission.js"

  camp_id = get_campagne_id

  # retrieve list of missions for selected campaign
  @missions = mission_by_campaign( camp_id )

  erb :admin_mission
end

次に、/missions_by_campaign に ajax 呼び出しを配置し​​、それを使用してページを更新します。作成する必要があるコードは他にもありますが、これにより、私が話していることのアイデアが得られます。

于 2012-09-10T13:49:05.770 に答える