简体   繁体   中英

Rails View not updating after jQuery Ajax call

I'm in the middle of my first rails project, and have reached the stage where I want to change the ORDER BY of my models' index depending on the value of a SELECT tag.

I have the following onchange in my index.html.erb

<div id="sortBy">
        <span>Sort by:</span>
        <%= select_tag "sort_by", options_for_select([ "Newest first", "Oldest first" ], "Newest first"), { :onchange => "changeSortOrderJs(this.value)" } %>
</div>

That should update this:

<% @horses.each do | horse | %>
   <%= horse.name %>
<% end %>

This calls the following method in my coffeescript asset ( prefixed with @ since it is an anon function):

@changeSortOrderJs = (val) ->
  $.ajax
    type: 'GET'
    url: '/horses'
    data: order: val

This maps to my index action in the HorsesController

def index
        order = params[:order]

        if(order == nil) 
            order = 'Newest first'
        end

        @horses = Array.new

        if order == 'Newest first'

            @horses = Horse.all.order("created_at DESC")

        elsif order == 'Oldest first'

            @horses = Horse.all.order("created_at ASC")
        end

        //tried this later but didn't work either
        respond_to do |format|
            format.html
        end
    end

I can see in my development.log that is working and the @horses are being populated in their correct order. But the view does not refresh.

If I use respond_with(@horses) and then a success callback in the ajax call, ie

@changeSortOrderJs = (val) ->
  $.ajax
    type: 'GET'
    url: '/horses'
    data: order: val
    success: (result) ->
      $('body').html(result)

then it does work and the horses get reordered. But I would rather not replace the whole body this way.

I thought the whole point with instance variables was that you could redefine them and the view would update automatically?

The instance variables don't just magically update the page. You have to use the success function like you're doing in the last segment of code. If you want the instant update you should look into using Knockout.js or something like that

Also, if you plan on rendering partials you'll have to do so outside of a Coffeescript file. For example, in your controller do:

respond_to do |format|
  format.js
end

And app/controllers/horses/index.js do:

container = $('#your_div_here');

<% @horses.each do |horse| %>
  container.prepend( "<%= j render( :partial => 'horses/horse', :locals => { :horse => horse } ) %>" );
<% end %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM