2013-04-12 5 views
1

Я полный новичок в мире RoR.Вставить рубин внутри javascript

Хотя я сгенерировал некоторый код, используя эстакады рельсов. Я также могу отправить форму через ajax, используя: remote => true.

И форма отправляется, красива и чиста! Но я хочу отобразить некоторые данные, которые были возвращены с моего контроллера, используя link_to, чтобы создать ссылку на маршрут/ресурс.

Я попытался создать .js.erb файл и встроить код в него, но он дает мне ошибку говоря:

undefined method `link_to' 

код .js.erb

$(document).ready(function(){ 


$("#new_post").bind('ajax:success', function(xhr, data, status){ 
    console.log(data) 
    if(data.errors){ 
     console.log("Error!") 
    } 
    else{ 
     var user_name = data.user; // json is contained in data variable   
     $("#recent_posts").prepend("<%= j link_to(user_name, '#') %>"); 
    } 
}); 

}); 

Где я ошибаюсь?

+0

Не могли бы вы включить свой 'код .js.erb' файла? – Stefan

+0

После этого вы можете поместить код Ruby в кавычки, чтобы не разорвать ваш .prepend() –

+0

. Каков путь к вашему файлу .js.erb? Если это не в приложении/views/_controller_name_, вы не можете быть в области с доступом к вспомогательным методам представления, например link_to. Чтобы проверить, так ли это, попробуйте явно вызвать область, заменив 'link_to' на' ActionController :: Base.helpers.link_to' – omnikron

ответ

1

Я думаю, что есть несколько источников ошибок здесь:

undefined method `link_to' 

Это весьма необычно, поскольку link_to является стандартным помощником вида. Вы уверены, что пространство до link_to действительно является пространством, а не каким-то другим невидимым персонажем (иногда вы получаете их, например, на OSX, когда используете space, удерживая alt). Кроме того, ваш js erb должен находиться в пространстве имен ваших контроллеров, но поскольку он выполняется, когда вы выполняете действие, это, по-видимому, имеет место.

$(document).ready(function(){ 

Вам не нужно будет использовать это в .js.erb шаблонов, так как нет готового события увольняют. jQuery выполняет скрипт сразу, если DOM все равно готов, поэтому он не повредит (обычно), это просто лишний.

$("#new_post").bind('ajax:success', function(xhr, data, status){ 

Это большая проблема. Теперь, когда вы прикрепляете обработчик, он будет прикрепляться каждый раз, когда форма будет отправлена, и сервер вернет данные. Итак, если есть ошибка, и форма будет отправлена ​​и возвращена во второй раз, вы либо получите сообщение console, либо вставку якоря, выполненную два раза. Так что будьте готовы к этому событию:

$("#new_post").not('.registered').addClass('registered').bind('ajax:success', function(xhr, data, status){ 

Это предотвратит несколько обработчиков событий.

Тогда есть третья проблема:

var user_name = data.user; // json is contained in data variable   
$("#recent_posts").prepend("<%= j link_to(user_name, '#') %>"); 

Здесь вы пытаетесь использовать переменную, назначенную в JavaScript в erb инлайн рубина. Это не сработает, так как рубиновая переменная user_name оценивается серверами при визуализации шаблона. С другой стороны, назначение переменной javascript оценивается в браузере, когда клиент получает визуализированный шаблон с сервера. Так что ты можешь сделать?

link_to не все, что магия. Он просто отображает привязную метку. Таким образом, это же можно сделать так:

var user_name = data.user; // json is contained in data variable   
$("#recent_posts").prepend(["<a href='#'>", user_name, "</a>"].join('')); 

Пока что так хорошо.Самая большая проблема, которую вы испытываете, заключается в следующем: сервер не может вернуть как обработанный .js.erb шаблон , так иjson данные сразу. Таким образом, данные, которые вы получаете в вашей функции javascript, будут только отображаемой строкой шаблона .js.erb. Связь с сервером в JSON действительно самое лучшее, так что давайте забудем о рельсах интегрированной обработки формы и написать его сами:

  1. Удалить :remote => true из вариантов формы

  2. Добавить :format => :json в свой create маршрут

    resources :posts, :only => [:create], :format => :json 
    resources :posts, :except => [:create] 
    
  3. Добавить JavaScript в ваших активов, который обрабатывает вашу форму удаленно

    // after DOM ready 
    
    var form = $('#new_post'); 
    form.on('submit', function(e) { 
    
        $.ajax({ 
        url: form.prop('action'), 
        type: form.prop('method') || 'POST' //for create action, 
        data: form.serializeArray(), 
        dataType: form.data('type') || 'json', 
        success: function(data, status, xhr) { 
          var user_name = data.user; // json is contained in data variable   
          $("#recent_posts").prepend(["<a href='#'>", user_name, "</a>"].join('')); 
        }, 
        error: function(xhr, status, error) { 
         console.log('error') 
        } 
        }); 
    
        return false; //prevent normal submit 
    
    }); 
    
  4. Теперь вы готовы вернуть чистый JSON с сервера:

    render :json => resource.to_json(:include => :errors) 
    
+0

Большое спасибо. Мне нужен параметр link_to, чтобы я мог ссылаться на путь к ресурсу. В любом случае ваш ответ стал еще более ощутимым. Приветствия! – swaroopsm

Смежные вопросы