Рельсы 5.2. Предоставление части js.erb из вспомогательного метода

У меня есть модель под названием «Вопрос», и у нее есть действие create;
Моя цель - мгновенно отобразить мгновенное сообщение, используя вспомогательный метод ( show_alertнапример), когда экземпляр недействителен.

question_controller.rb

def create
    question = Question.new(question_params)
    if question.save then
        redirect_to show_question_path(question.id)
    else
        show_alert(:warning, question.errors)
    end
end

application_controller.rb

    helper_method :show_alert

    def show_alert(type, message)
          @type = type; @msg = message
          respond_to do |format|
            format.js { render :template => 'alert.js.erb'}
          end
    end

var div = $ ( '<div> </ div>' ). addClass ( `alert alert - $ {@ type}` ) $ ( '<ul> </ ul>' ). append ( $ ( '<li> </ li>' ). html ( @msg ) div . append ( ul ) $ ( '#alerts' ). html ( div )

alert.js.erb

Но вместо отображения вспышки я получаю только код частичного изображения на белом экране.

см. скриншот

Поскольку я использовал response_to, я получил еще одну ошибку: ActionController :: UnknownFormat

Мне нужен фрагмент кода alert.js.erbдля выполнения, чтобы сделать флеш-память, я думаю, что трюк находится где-то в renderфункции, но два часа работы в Google - это просто пустая трата времени.

Пожалуйста помоги! заранее спасибо

javascript,ruby-on-rails,

0

Ответов: 3


0 принят

ActionController::UnknownFormat error появляется, потому что браузер отправляет запрос HTML серверу Rails, но блок response_to только указал, что делать в случае запроса javascript с веб-сервера.

Вам нужно будет добавить немного Ajax для достижения того, чего вы хотите. См. Этот учебник по Ajax. https://www.tutorialspoint.com/ruby-on-rails/rails-and-ajax.htm

Ajax отправит js-запрос в браузер в фоновом режиме (т. Е. Браузер не обновит или не покажет никаких признаков загрузки). Этот запрос js будет отправлен на сервер Rails, и он вернет файл .js.erb, содержащий скрипт, в браузер. Теперь, поскольку этот скрипт был возвращен в ответ на запрос Ajax браузером, браузер уже знает, что это javascript, который нужно выполнить.

Если вы не хотите внедрять Ajax, у вас есть альтернатива делать что-то подобное в вашем контроллере создания:

def create
    question = Question.new(question_params)
    if question.save then
        redirect_to show_question_path(question.id)
    else
        redirect_to new_question_path(error: question.errors) #new_question_path is the action that displays the question form to the user
    end
end

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

def new
    @error=params[:error]
    #rest of the code... 
end

А затем где-то в вашем new.html.erb (или любом другом имени файла html.erb)

<script>
    <% if @error %>
        var div = $('<div></div>').addClass(`alert alert-<%= @type %>`)
        $('<ul></ul>').append( $('<li></li>').html(<%= @msg %>)
        div.append(ul)
        $('#alerts').html(div)
    <% end %>
    // you might need to tweak the variable names in controller or the above code
</script>

(Этот код выше может быть не идеальным, его просто дать идею)

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


0

По умолчанию все выходные данные из помощников экранируются. Чтобы показать HTMl as-is, вам нужно использовать метод html_safe ( https://apidock.com/rails/v4.2.1/String/html_safe ). См. Использование помощников в представлении выходит из html?


0

Я не могу быть уверен в этом, не увидев ваш alert.js.erb, но может быть, вам нужно использовать escape_javascript в вашем alert.js.erb

Что-то вроде (и я не проверял это) в вашем alert.js.erb

$('<%= escape_javascript("#{type} - #{msg}") %>').appendTo("#alert")

Вы можете узнать больше об этом в Rails Guides - Работа с Javascript в Rails

Надеюсь это поможет!

JavaScript, рубин-на-рельсы,
Похожие вопросы