如何在Rails中调用javascript后期呈现?

如何在Rails中调用javascript后期呈现?,javascript,jquery,ruby-on-rails,render,facebox,Javascript,Jquery,Ruby On Rails,Render,Facebox,这是facebox弹出内容 <div class="form_container"> <% form_remote_tag :url => { :action => 'custom', :d=>params[:day], :h=>params[:hour] }, :class => 'general-form', :update => 'grid['+params[:day]+']['+params[:h

这是facebox弹出内容

<div class="form_container">
  <% form_remote_tag :url => { :action => 'custom', :d=>params[:day], :h=>params[:hour]  },
        :class => 'general-form',
        :update => 'grid['+params[:day]+']['+params[:hour]+']',
        :success => 'handle_success('+params[:day]+','+params[:hour]+')' do -%>
    <table width="300px" style="border:none">
      <% @availability_hash.each_key do |availability_id| %>
        #some view related stuff
      <% end %>
    </table>
    <input type="submit" class="btn" value="Re-assign Coaches" />
  <% end %>
</div>
这是部分(_grid_item.html.erb)


: 
这是主页面中使用的脚本

<script type="text/javascript">
  jQuery(document).ready(function($) {
    jQuery('a[rel*=facebox]').facebox()
    $.facebox.settings.opacity = 0.5
  })

  function handle_success(d,h){
    jQuery(document).trigger('close.facebox');
    var link_div = document.getElementById('link['+d+']['+h+']');
    jQuery(link_div).facebox();
  }
</script>

<div class="master_view">
  <table class="master_scheduler_table" id="master_scheduler_table" >
    <% HOURS_IN_A_DAY.each do |hour| %>
      <tr>
        <td><%= time(hour*2) %></td>
        <% DAYS_IN_A_WEEK.each do |day| %>
          <td id="grid[<%= day %>][<%= hour %>]" >
            <%= render(:partial => "grid_item" , :locals => {:day=>day, :hour=>hour, :data=>@data[day][hour]}) %>
          </td>
        <% end %>
      </tr>
    <% end %>
  </table>
</div>

jQuery(文档).ready(函数($){
jQuery('a[rel*=facebox]')。facebox()
$.facebox.settings.opacity=0.5
})
函数句柄_成功(d,h){
jQuery(document.trigger('close.facebox');
var link_div=document.getElementById('link['+d+']['+h+']');
jQuery(link_div).facebox();
}
“grid_item”,:locals=>{:day=>day,:hour=>hour,:data=>@data[day][hour]})%>
渲染完成后,我想调用一个脚本。怎么做?我正在视图中使用form_remote_标记

渲染部分是在Ajax上下文中完成的,不会重新加载页面。form_remote_标记有一个:success方法,我可以在其中调用javascript。不幸的是,我放在success方法中的javascript在渲染完成之前被调用。但是,我需要在渲染完成后调用javascript

为了清楚起见,我只是简单地提出了一条警告信息。实际上,我正在对正在渲染的DIV元素调用一个facebox()方法。在呈现DIV元素之后,应该将facebox()(jQuery的)方法应用于该元素,只有这样它才会有效


编辑:我已经添加了完整的代码。如果您可以看到,我将在Ajax返回后调用javascript方法handle_success。(我很抱歉将:success方法放在了partial中)。在实际渲染完成之前调用handle_success。这应该是“在”它完成之后

渲染在服务器端完成,一旦组成了整个页面,生成的HTML将返回给客户端。因此,在这种情况下无法执行客户端脚本。要在加载页面后调用某些javascript,可以使用
onload
事件处理程序:

<script type="text/javascript">
window.onload = function() {
    // put your code here
};
</script>

window.onload=函数(){
//把你的代码放在这里
};
或者,如果您使用:


$(函数(){
//把你的代码放在这里
});
或者,如果您使用:


document.observe(“dom:loaded”,function()){
//把你的代码放在这里
});

呈现在服务器端完成,一旦组成整个页面,生成的HTML将返回给客户端。因此,在这种情况下无法执行客户端脚本。要在加载页面后调用某些javascript,可以使用
onload
事件处理程序:

<script type="text/javascript">
window.onload = function() {
    // put your code here
};
</script>

window.onload=函数(){
//把你的代码放在这里
};
或者,如果您使用:


$(函数(){
//把你的代码放在这里
});
或者,如果您使用:


document.observe(“dom:loaded”,function()){
//把你的代码放在这里
});

您的理解有点错误:

“提交标记具有:success方法 在这里我可以调用javascript。 不幸的是,我使用的javascript 投入成功的方法是获得成功 调用“before”,渲染是 完成。”

:success
方法用于提交成功的时间。不适用于提交后发生的任何事件!您需要在部分渲染完成后执行成功方法,而不是在单击提交按钮时执行!如果您熟悉jquery,我建议您采用不引人注目的方式。我从不依赖内置助手,因为它缺乏灵活性,而且我讨厌使用内联javascript。。你将无法缓存它。我将把我所有的javascript都放在一个缩小的js文件中,这个文件可以缓存一次,而不是代码到处传播。无论如何,我只是偏离了重点

其次,您不应该为ajax调用呈现分部。这将始终刷新您的页面。相反,您应该为特定的控制器操作创建一个
.js.erb
.xml.erb
文件

既然你还没有给出你在你的部分文章中所呈现的内容,我将为你提供一个大致的答案。请与我们分享您的部分代码,以便我们知道您到底想要什么。还提供要在成功时修改的HTML标记的
选择器id/class
(呈现后即..)

如果您想要更好的方式,我将为您提供我用于ajax的配置:


在application.js中:

$.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/xml")}
});

$(document).ready(function() {
    //  All non-GET requests will add the authenticity token
    //  If not already present in the data packet
    $("body").bind('ajaxSend', function(elm, xhr, s) {
      if (s.type == "GET") return;
      if (s.data && s.data.match(new RegExp("\\b" + window._auth_token_name + "="))) return;
      if (s.data) {
        s.data = s.data + "&";
        } else {
            s.data = "";
            // if there was no data, $ didn't set the content-type
            xhr.setRequestHeader("Content-Type", s.contentType);
        }
        s.data = s.data + encodeURIComponent(window._auth_token_name) + "=" + encodeURIComponent(window._auth_token);
    });
  });

在IE和SAFARI中,accept头默认为text/html,而不是text/xml或text/javascript。要更正此问题,请将其添加到application.controller.rb;解决所有跨浏览器问题:

  def correct_safari_and_ie_accept_headers
    ajax_request_types = [ 'text/javascript', 'application/json', 'text/xml']
        request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
  end

在版面
your_layout.html.erb
中,将以下内容添加到标题中:

<% if protect_against_forgery? %>
    <script type="text/javascript" charset="utf-8">
        //<![CDATA[
            window._auth_token_name = "#{request_forgery_protection_token}";
            window._auth_token = "#{form_authenticity_token}";
        //]]>
    </script>
<% end %>
<%= javascript_include_tag 'jquery.taconite.js','application.js', :cache => true %>

现在,在用于渲染部分
渲染(:partial=>“grid\u item”)
的操作中,将操作更改为

   def your_action_here

      # CODE GOES HERE:
      # @instance_variable_to_store_stuff = some_stuff
      respond_to do |format|
        format.html {redirect_to :action => :index}
        format.xml #EXTREMELY IMPORTANT. THIS CORRESPONDS TO your_action_here.xml.erb
      end
   end
现在在您的
视图/your\u controller/
中创建一个
your\u action\u here.xml.erb
文件。在该文件中,您可以添加渲染发生后执行的javascript代码。这一行动将以两种方式作出回应。如果用户在浏览器中禁用了javascript,它将用html数据响应,否则它将默认为xml数据。现在,这就是塔克尼特进入画面的地方。taconite的妙处在于它将所有基于jquery的DOM修饰符转换为符合XML的标记

不要执行
$(“#div”).append('YO!')
您可以执行以下操作:

<append select="#div">
  <div>YO!</div>
</append>
如果要执行多个DOM更新,可以执行以下操作,例如:

<taconite>
  <replace select="#div">
    <%=h @instance_variable_to_store_stuff %>
  <replace>

  <append select="#someotherelement_id">
    <div>I got appended to #someotherelement_id</div>
  </append>

  <slideUp select=".someelementwithaclass" />

  <slideDown select=".someelementwithanotherclass" />
</taconite>

我被附加到了#其他元素_id
您还可以使用eval标记在your_action_here.xml.erb中运行javascript,如下所示:

<taconite>
  <append select="#div">
    <%=h @instance_variable_to_store_stuff %>
  </append>

    <eval>
            alert("HO! HO! HO!"); 
            setTimeout(($("#flash").effect("highlight", {}, 3000).slideUp("slow")), 5000);
        $("form")[0].reset();

    </eval>
</taconite>

警惕(“嗬!嗬!嗬!”);
setTimeout($(“#flash”).effect(“highlight”),{},3000.slideUp(“slow”)),5000);
$(“表单”)[0]。重置();
您应该记住的一件事是,所有的xml标记都应该是关闭的,而不是
   def your_action_here

      # CODE GOES HERE:
      # @instance_variable_to_store_stuff = some_stuff
      respond_to do |format|
        format.html {redirect_to :action => :index}
        format.xml #EXTREMELY IMPORTANT. THIS CORRESPONDS TO your_action_here.xml.erb
      end
   end
<append select="#div">
  <div>YO!</div>
</append>
<taconite>
  <append select="#div">
    <%=h @instance_variable_to_store_stuff %>
  </append>
</taconite>
<taconite>
  <replace select="#div">
    <%=h @instance_variable_to_store_stuff %>
  <replace>

  <append select="#someotherelement_id">
    <div>I got appended to #someotherelement_id</div>
  </append>

  <slideUp select=".someelementwithaclass" />

  <slideDown select=".someelementwithanotherclass" />
</taconite>
<taconite>
  <append select="#div">
    <%=h @instance_variable_to_store_stuff %>
  </append>

    <eval>
            alert("HO! HO! HO!"); 
            setTimeout(($("#flash").effect("highlight", {}, 3000).slideUp("slow")), 5000);
        $("form")[0].reset();

    </eval>
</taconite>
 <!-- IN HTML.ERB FILE -->
    <div class="form_container">
      <% form_tag({:action => :custom, :d => params[:day], :h => params[:hour]}, {:class => "general-form"}) do %>
        <table width="300px" style="border:none">
          <% @availability_hash.each_key do |availability_id| %>
            <tr>
              <td width="50%"><b><%= CoachAvailability.find(availability_id).coach_availability_template.coach.display_name %></b> (X/8)</td>
              <td><%= select_tag('template['+availability_id.to_s+']', options_for_select([["Available", 0],["Scheduled", 1]], :selected => CoachAvailability.find(availability_id).status )) %></td>
            </tr>
          <% end %>
        </table>
        <%= submit_tag "Re-assign Coaches", :class => "btn" %>
      <% end -%>


//In your JS file
$(".general-form").live('submit', function() {
    $.post(this.action, $(this).serialize(), "_method=post");
    return false;
})


#In your controller
def custom
    master_scheduler
    h = params[:h].to_i
    d = params[:d].to_i
    @day = d
    @hour = h
    respond_to do |format|
      format.xml
    end
end

<!-- IN custom.xml.erb -->
<taconite>
    <append select="#div_changed_content">

         What ever changes you want to make. Your code is bit confusing. So i won't go deep into what should come here. You know what changes you want to make. :)

         Maybe you wanted to add this? How did you get data[:commited_coaches] and data[:available_coaches] without passing it through the partial?? 

         Anyways if you want to pass it now you can do so from the controller itself. By creating a @data_commited_coaches and @data_available_coaches and storing the above in that.



    <div class ="left_inner_element">
  <div class="l_upper_element">
    <div class="coaches_committed"><%= data[:committed_coaches] %></div>
    <div class="coaches_available"><%= data[:available_coaches] %></div>
  </div>
  <div class="l_lower_element"><%= data[:classes] %> : <%= data[:avg_attendance] %>
  </div>
</div>
<a id="link[<%= day %>][<%= hour %>]" rel="facebox" href="coach_selector_popup?(bla bla)" >
  <div class ="right_inner_element right_inner_color_<%= data[:color_code] %>">
    #some ui stuff
  </div>
</a>


    </append>   

    <eval>
       // You can call the handle_success here: If i guessed right, this is what you want to do.
       handle_success(<%= @day %>,<%= @hour %>);
    </eval>

</taconite>