我已经没有想法了,并且没有提示解决方案,所以我希望有人可以让我摆脱这种混乱,因为我真的,真的被卡住了。
我的一条路线查询数据库并通过一堆实例变量(@campagnes和@missions)通过erb呈现数据。不用担心,一切正常。
我已经设置了一个jQuery函数,可以帮助我根据下拉选择器过滤我桌面上的数据。因此,如果用户在下拉列表中更改了所选值,则jQuery $ .ajax方法会重新加载页面,将所选值传递给“get”路径。
这是我没有得到的。调用有效,它成功,参数传递给路由,它们用于从数据库中读取,但是所有具有新数据集REFUSE的实例变量都要在视图中进行评估。相反,仍然使用旧的(在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é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!");
});
}
});
});
答案 0 :(得分:1)
实例变量仅用于从ERB模板创建HTML / JavaScript视图,因此,无需重新加载页面,任何更改这些变量值的数量都不会影响已作为视图呈现的内容。
您的Ajax调用应该以一种JavaScript可以用来操纵页面DOM的形式返回页面所需的任何新数据。例如,返回json构造的服务器端的一个很好的块。
另外,您可能需要查看DataTables,这是一个很好的jQuery插件,可以帮助操作表数据。它有一些很好的Ajax处理程序。
答案 1 :(得分: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);
});
});
我确信有更好的方法可以做到这一点,我只是不知道它是什么。
答案 2 :(得分:0)
我的建议是为campagne(广告系列?)列表设置完全独立的路线,例如
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
然后将ajax调用放入/ missions_by_campaign并使用它来更新页面。 您需要编写更多代码,但它可以让您了解我在说什么。