Я не могу на всю жизнь заставить RJS заменить innerHTML элемента на атрибут переменной экземпляра, то есть что-то вроде @thing.name
Я покажу весь код (упрощенный от фактического проекта, но все еще завершенный), и я надеюсь, что решение кому-то станет очевидным ...
В RoR я сделал простую страницу со случайным китайским символом.
Это Word
объект с атрибутами chinese
и english
.
Нажав на ссылку под названием "Что это?" показывает атрибут english
, используя RJS. В настоящее время также скрывается «Что это?» ссылка и показывает "Попробуйте другой?" ссылка, которая просто перезагружает страницу, фактически начиная с нового случайного символа.
Это нормально, но на странице есть другие элементы, которые выполняют свои собственные запросы к базе данных, поэтому я хотел бы загрузить новый случайный символ с помощью вызова AJAX, оставив остальную часть страницы в покое.
Это оказалось сложнее, чем я ожидал: у меня нет проблем с заменой HTML-кода с использованием link_remote_to и page.replace_html, но я не могу заставить его отобразить что-либо, содержащее переменную экземпляра.
У меня есть ресурс Word и ресурс Page, на котором есть домашняя страница, где происходит все это веселье. В PagesController я сделал несколько способов получить случайные слова. Либо один работает нормально ...
Вот код:
class PagesController < ApplicationController
def home
all_words = Word.find(:all)
@random_word = all_words.rand
@random_words = Word.find(:all, :limit => 100, :order => 'rand()')
@random_first = @random_words[1]
end
end
Кроме того, вызов SQL с :limit => 100
на всякий случай, я думаю о каком-то способе циклически переключаться между этими случайными словами. Прямо сейчас это не полезно. Кроме того, насколько я знаю, rand () специфичен для MySQL.
В представлении домашней страницы (это HAML), у меня есть это:
#character_box
= render(:partial => "character", :object => @random_word) if @random_word
#whatisthis
= link_to_remote "☝ what is this?", :url => { :controller => 'words', :action => 'reveal_character' }, :html => { :title => "Click for the translation." }
#tryanother.{:style => "display:none"}
= link_to "try another?", root_path
Обратите внимание, что # в этом случае представляют div (с заданными идентификаторами), а не комментарии, потому что это HAML.
Частично "персонаж" выглядит следующим образом (это эрб, без реальной причины):
<div id="character">
<%= "#{@random_word.chinese}" } %>
</div>
<div id="revealed" style="display:none">
<ul>
<li><span id="english"><%= "#{@random_word.english_name}" %></span></li>
</ul>
</div>
Файл reve_character.rjs выглядит следующим образом:
page[:revealed].visual_effect :slide_down, :duration => '.2'
page[:english].visual_effect :highlight,
:startcolor => "#ffff00",
:endcolor => "#ffffff",
:duration => '2.5'
page.delay(0.8) do
page[:whatisthis].visual_effect :fade, :duration => '.3'
page[:tryanother].visual_effect :appear
end
Это все прекрасно работает.
Но если я попытаюсь превратить link_to "try another?"
в link_to_remote
и указать его на шаблон RJS, который заменяет элемент «character» чем-то новым, он работает только тогда, когда я заменяю innerHTML статическим текстом. Если я попытаюсь передать туда переменную экземпляра, она никогда не будет работать.
Например, допустим, я определил второе случайное слово в разделе Pages # home ...
Я добавлю @random_second = @random_words[2]
туда.
Затем в представлении домашней страницы я заменю "попробовать другой?" ссылка (ранее указывающая на root_path
), с этим:
= link_to_remote "try another?", :url => { :controller => 'words', :action => 'second_character' }, :html => { :title => "Click for a new character." }
Я создам этот новый шаблон RJS в app / views / words / second_character.rjs, и простой тест, подобный этому, показывает, что он работает:
page.replace_html("character", "hi")
Но если я изменю это на:
page.replace_html("character", "#{@random_second.english}")
Я получаю сообщение об ошибке, сообщив, что я выдал ему нулевой объект:
ActionView :: TemplateError (неопределенный метод `english_name 'для nil: NilClass) в строке # 1 файла app / views / words / second_character.rjs:
1: page.replace_html ("символ", "# {@ random_second.english}")
Конечно, на самом деле создание экземпляров @random_second, @random_third и т. Д. До бесконечности было бы нелепым в реальном приложении (я бы в конечном итоге придумал какой-нибудь лучший способ продолжить захват новой случайной записи без перезагрузки страницы), но главное в том, что я не знаю, как заставить любую переменную экземпляра работать здесь.
Это даже не приближается к моему идеальному решению рендеринга партиала, включающего указанный мной объект, например:
page.replace_html 'character', :partial => 'new_character', :object => @random_second
Поскольку я не могу заставить переменную экземпляра работать напрямую, я, очевидно, не могу заставить ее работать через частичное.
Я пробовал разные вещи, такие как:
:object => @random_second
или
:locals => { :random_second => @random_second }
Я попытался добавить их повсеместно - в опциях link_to_remote
, наиболее очевидно - и изучить, что передается в параметрах, но безрезультатно. Именно в этот момент я понимаю, что не знаю, что делаю.
Это мой первый вопрос здесь. Я ошибся в предоставлении всего необходимого кода, а не вкратце. Любая помощь будет принята с благодарностью.