Ruby On Rails 3, form_tag удален при ответе на запрос Ajax - PullRequest
10 голосов
/ 26 октября 2010

спасибо за чтение этого поста. Последние несколько дней я застрял в проблеме с RoR. У меня есть форма в index.html.erb как:

<head>
    <title>Ajax List Demo</title>
    <%= javascript_include_tag :defaults %>  
    <%= csrf_meta_tag %>  
</head>
<body>
  <h3>Add to list using Ajax</h3>

  <% form_tag :action => :list , :method=>:get, :remote=>true  do %>
    Enter the public url:<%= text_field_tag 'url' ,'', :size => 80 %>
    <%= submit_tag "Find" %>
  <% end %>

  <div id="my_list">
  </div>
</body>

В контроллере у меня есть:

 def list
    puts "here!!!!"
    reader = Reader.new
    @profiles =  reader.processURL(params[:url]) #profileList = 
    respond_to do |format|
      #format.html { render :partial=>true, :locals => { :profiles => @profiles}}#{          render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}} 

format.js {render :content_type => 'text/javascript', :locals => { :profiles => @profiles}}

# index.html.erb
      #   format.rss     render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}
    end

И JS-файл для удаленного UJS в виде list.js.erb

$("#my_list").html("<%= escape_javascript(render(:partial => "list"))%>");

Проблема в том, что я не могу получить результаты для отображения частичного _list.html.erb в теге div my_list. Я получаю пустую страницу, ошибка 406. Если я откомментирую HTML-код рендеринга в контроллере, я получу частичную обратную визуализацию в браузере. Я застрял, я хочу отправить форму и результаты, чтобы выскочить в div my_list. Я новичок в рельсах, поэтому, если я упускаю что-то очевидное, не стесняйтесь указывать мне на это ... Я определенно готов попробовать.


Изменил это на:

<html>
    <head>
        <title>Ajax List Demo</title>
        <h1>Listing posts</h1>
           <%= javascript_include_tag 'jquery.js' %>  
    <%= csrf_meta_tag %>  
    </head>
    <body>
        <h3>Add to list using Ajax</h3>

        <% form_tag :action => :doit , :method=>:get, :remote=>true  do %>
        Enter the public url:<%= text_field_tag 'url' ,'', :size => 80 %>
        <%= submit_tag "Find" %>
        <% end %>

        <div id="my_list">
                   </div>

Контроллер:

def doit
    puts "here!!!!"
    reader = Reader.new
    @profiles =  reader.processURL(params[:url])
    respond_to do |format|
 #     format.html {render :partial=>true, :locals => { :profiles => @profiles}}#{    render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}} 
      format.js #{render :content_type => 'text/javascript', :locals => { :profiles => @profiles}}
      # index.html.erb
      #   format.rss     render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}
    end

JS _doit.js.erb $ ("# my_list"). html ("<% = escape_javascript (render (:part =>" doit "))%>");

И, наконец, частичное:

_doit.html.erb.

Однако я все еще получаю ошибку 406, у меня нет дубликатов _doit js или erb. Что-то выделяется как неправильное из этого? Еще раз спасибо!


Еще одно обновление:

Я думаю, что форма не отображается правильно:

Это оказано:

<% form_tag :action => :doit , :remote=>true, :id => 'myform' do %>
        Enter the public url:<%= text_field_tag 'url' ,'', :size => 80 %>
        <%= submit_tag "Find" %>
        <% end %>

Это:

<form accept-charset="UTF-8" action="/home/doit?id=myform&amp;remote=true" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="&#x2713;" />
<input name="authenticity_token" type="hidden" value="MLuau4hvfdGO6FrYCzE0c0JzwHhHKZqjmV49U673sK8=" />
</div>        Enter the public url:
<input id="url" name="url" size="80" type="text" value="" />

    <input name="commit" type="submit" value="Find" />



        <input name="commit" type="submit" value="Find" />

Это добавление моего удаленного тега и идентификатора в строку запроса, не так ли?

Хорошо, наконец, есть подсказки, которые нужно заключить в скобки:

 <%= form_tag( { :action => 'doit' }, :multipart => true, :remote=>true, :id => 'myform' ) do %>

Хорошо, последнее обновление сегодня вечером: Теперь я получаю в логах:

Запущен POST "/ home / doit" для 127.0.0.1 в среду, 27 октября, 22:40:55 -0400 2010 Вот!!!! Обработка HomeController # doit как JS Параметры: {"commit" => "Find", "url" => "http://www.facebook.com/people/James-Stewart/653161299"," authenticity_token "=>" MLuau4hvf dGO6FrYCzE0c0JzwHhHKZqjmV49U673sK8 = "," utf8 "=>" Γ £ ô "} Rendered home / _doit.html.erb (4.0ms) Rendered home / doit.js.erb (9.0ms) Завершено 200 OK за 807 мс (Просмотров: 40,0 мс | ActiveRecord: 0,0 мс)

Я вижу как JS, и он говорит, что он делает мой JS / частичный. Однако я ничего не получаю на my_list div. Мой JS-файл:

$("#my_list").html("<%= escape_javascript(render(:partial => "doit"))%>");

Мой файл формы html.erb теперь имеет:

<script$('#myform').bind('ajax:success', function(evt, data, status, xhr){
    xhr.responseText;
  });></script>

Это похоже на то, что форма ничего не делает, что является хорошим признаком, не более 406 ошибок. Я знаю, что это близко, если кто-нибудь может указать, что мне нужно сделать в js, это было бы здорово, иначе я сделаю перерыв и попробую tmrw.


Хорошо, я думаю, что получение ответа обратно, а не рендеринг, как вы указали, было проблемой вчера, Стив.

Отладка JS в Firebug. Я вижу HTML, который я хочу отобразить в div, для этого:

http://localhost:3000/javascripts/prototype.js?1285674435/event/seq/1

Это означает, что я думаю, что теперь получаю ответ JS.

У меня есть это на странице формы:

<script>$('#myform').bind('ajax:success', function(evt, data, status, xhr){
    $('#my_list').html(eval(xhr.responseText));
  });</script>

Инспекции говорят, что он не знает, что такое myform, но я вставил: id => 'myform' в код Rails.


Опять же, спасибо, мне здесь очень помогли, и я хочу поделиться тем, как я наконец-то вернул это к сообществу.

Файл, js для метода doit (по умолчанию требуется лучшее имя действия контроллера) - doit.js

Код был в конечном итоге:

$("my_list").update("<%= escape_javascript(render(:partial => "doit"))%>");

По какой-то причине, оставив его как #my_list, не будет найдено в firefox, мне пришлось использовать firebug, чтобы наконец это выяснить.

Очевидно, что это отличается от способа, предложенного ниже, и я собираюсь поместить скрипт js обратно в форму, удалить файл .js.erb и посмотреть, как это работает. Я полагаю, я просто визуализирую частичное в ответе format.js? Кроме того, где все находят информацию о записи файлов UJS? Я ничего не знаю о синтаксисе для всего, что начинается с $.

Еще раз спасибо за помощь, наконец, чувствую, что я делаю успехи в изучении рельсов.

Ответы [ 4 ]

26 голосов
/ 27 октября 2010

Я разместил этот ответ в Hacker News, но полагал, что сообщество Stack Overflow также может принести пользу: -)

В Rails 3 драйверы javascript очень практичны (то есть ненавязчивы). Проблема в том, что ваше приложение возвращает браузеру строку javascript, но на странице нет ничего, что выполняло бы этот javascript в контексте страницы.

Драйвер rails.js ujs связывается с формами и ссылками с помощью data-remote=true, что и делает :remote => true, чтобы они отправляли свои запросы удаленно, но на этом магия Rails останавливается.

Хорошей новостью является то, что удаленные запросы запускают некоторые события, к которым вы можете привязать, которые дают вам доступ к данным, возвращаемым сервером (которые запускаются в следующем порядке):

  ajax:before
  ajax:loading
  ajax:success
  ajax:complete
  ajax:failure
  ajax:after

Вам необходимо привязать событие к ajax:success событию вашей формы. Итак, если ваша форма имеет идентификатор «myform», вы бы хотели что-то вроде этого на своей странице:

  $('#myform').bind('ajax:success', function(evt, data, status, xhr){
    eval(xhr.responseText);
  });

xhr.responseText - это то, что возвращает ваш сервер, поэтому он просто выполняет его как javascript.

Конечно, также необходимо связать событие сбоя с некоторой обработкой ошибок.

Я обычно даже не использую метод action.js.erb для возврата javascript, я просто заставляю свой контроллер отображать HTML-код частично, а затем у меня на странице есть привязка, подобная этой:

  $('#myform').bind('ajax:success', function(evt, data, status, xhr){
    $('#target-div').html(xhr.responseText);
  });

На самом деле я сейчас нахожусь в процессе написания полной статьи по этому вопросу, но, надеюсь, этого достаточно, чтобы вы начали.

РЕДАКТИРОВАТЬ: я закончил эту статью, полностью объясняя удаленные ссылки и формы в Rails 3. Может быть, это поможет:

Rails 3 Удаленные ссылки и формы: Полное руководство

6 голосов
/ 12 февраля 2011

Если вы посмотрите на визуализированный источник вашей страницы, вы должны заметить ошибку в атрибутах полей.

Правильный способ сделать это так:

<%= form_tag({:action => 'list'}, :remote => true %>

Обратите внимание на фигурные скобки, очень важно!В качестве альтернативы вы могли бы сделать:

<%= form_tag('list', :remote => true %>
2 голосов
/ 26 октября 2010

У вас есть 2 части с именем _list?Может быть, это вызывает проблемы, и вы должны немного конкретизировать:

$("#my_list").html("<%= escape_javascript(render(:partial => "list.html.erb"))%>");

Я не уверен, поможет ли это, но если вы используете в IE, имейте в виду, что IE отправляет некоторые заголовки, которые указывают на то, как реагирует ваш контроллер.Таким образом, вы можете отправлять запрос Ajax с IE, но ваше приложение Rails считает, что это простой HTML-запрос.

Мне пришлось настроить jQuery, чтобы сначала удалить текущие заголовки, а затем добавить только заголовок javascript:

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

})

1 голос
/ 26 октября 2010

Использование list в качестве имени вашей функции в контроллере может быть проблемой.Это имя используется внутри Rails.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...