Jquery 在ajax调用后,视图中未计算Sinatra实例变量

Jquery 在ajax调用后,视图中未计算Sinatra实例变量,jquery,ajax,sinatra,Jquery,Ajax,Sinatra,我已经没有什么想法了,在网络上也没有任何解决办法,所以我希望有人能帮我摆脱困境,因为我真的,真的被卡住了 我的一个路由查询数据库,并通过一组实例变量(@campagnes和@missions)通过erb呈现数据。不用担心,一切正常 我已经设置了一个jQuery函数,它可以帮助我根据下拉选择器筛选表中的数据。因此,如果用户更改下拉列表中的选定值,jQuery$.ajax方法将重新加载页面,并将选定值传递给“get”路由 这是我不明白的。调用工作,成功,参数被传递到路由,它们被用来从数据库中读取,但

我已经没有什么想法了,在网络上也没有任何解决办法,所以我希望有人能帮我摆脱困境,因为我真的,真的被卡住了

我的一个路由查询数据库,并通过一组实例变量(@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
我的观点(编辑为重要内容)


在拉扯了很多头发之后,我找到了一种解决办法(我不太喜欢),并对这种行为做出了解释(尽管我不是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);
    });

}); 

我确信有更好的方法可以做到这一点,我只是不知道它是什么。

实例变量仅用于从ERB模板创建HTML/JavaScript视图,因此,在不重新加载页面的情况下,这些变量的值的任何更改都不会影响已呈现为视图的内容

Ajax调用应该以JavaScript可以用来操纵页面DOM的形式返回页面所需的任何新数据。例如,返回一个漂亮的json构建的服务器端块


另外,您可能还想看看一个不错的jQuery插件,它可以帮助您操作表数据。它有一些很好的Ajax处理程序

我的建议是为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\u by\u活动中,并使用该调用更新页面。
您需要编写更多的代码,但它让您了解我在说什么。

谢谢Dave,这本应该是显而易见的,但我对这一点很陌生。每个人都必须从某个地方开始:-)我从Sinatra、ActiveRecord开始了我的Ruby之旅,jQuery作为所有新技术,我想我会同时学习,如果你看看我在这里提出的各种问题,我的学习曲线似乎非常典型。我发现将呈现的页面视为真实视图代码(javascript)的网格非常有用,真实视图代码通过AJAX调用从Sinatra提供的API填充自己,Sinatra的助手和路由通过ActiveRecord将内容读写到DB(有些人更喜欢Sequel;六个半其他)
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