Какой лучший способ сделать UJS в рельсах, когда у вас есть многократно используемый виджет? - PullRequest
0 голосов
/ 11 мая 2011

В моем текущем проекте у меня есть пара случаев, когда у меня есть форма многократного использования, которая существует внутри частичного рельса.Эта форма отправляется на конкретный контроллер через ajax (: remote => true).Контроллер делает некоторые вещи, а затем возвращает обратно соответствующий js.erb, чтобы изменить страницу с помощью javascript.

Это прекрасно работает, когда у меня есть одно представление.Но проблема, кажется, возникает, когда эта многоразовая часть существует в нескольких представлениях.В представлении 1 мне может потребоваться выполнить совершенно другой набор команд javascript, чем в представлении 2.

В качестве конкретного примера, скажем, у меня есть контроллер комментариев, который выполняет обычные операции CRUD.

Теперь у меня есть частичное имя _comments_box.erb.Этот _comments_box.erb содержит возможность отправки комментария через простую строку:

- form_for comment, :url => post_comments_path(post), :remote => true do |f|

. Он передает метод создания comments_controller.rb, который выглядит примерно так:

def create
   ... do some stuff, like create a new comments model

   respond_to do |format|
      # will respond with create.js.erb
      format.js
   end

end

create.js.erb, в свою очередь, добавляет комментарий к представлению, возможно, делая кучу других обновлений для DOM.

Скажем, я отрисовываю _comments_box.erb в представлении с именем post_summary.erb.Теперь у меня есть другое представление, post_detail.erb, для которого требуется тот же _comments_box.erb.Однако post_detail.erb требует, чтобы я обновлял абсолютно разные div в DOM в ответ на новый комментарий.

Мне нужно создавать разные JS-ответы для каждого экземпляра.Поэтому я могу либо:

  • Создать альтернативный метод контроллера, скажем, create_2.Передайте некоторый параметр в _comments_box.erb из post_detail.erb в партиал _comments_box.erb, чтобы он знал, какой метод контроллера использовать.Это позволит мне иметь отдельный файл _create_2.js.erb, который позволит мне независимо управлять представлением post_detail.erb.
  • Забудьте об использовании js.erb в целом, просто используйте старый AJAX и получите обратно JSONи полностью обработать манипуляции с JavaScript на стороне клиента.

Кажется, вариант 1 позволяет мне продолжать использовать UJS, поддерживаемый Rails, что приятно.Но это также означает, что я, вероятно, буду добавлять много дублирующего кода везде, что раздражает.Могу ли я сделать это элегантно, продолжая использовать UJS?

Ответы [ 3 ]

3 голосов
/ 15 мая 2011

Это как раз цель Apotomo: http://apotomo.de/

Вот собственное описание:

Apotomo - это истинная структура виджетов MVC для рельсов. Виджеты основаны на ячейках и предоставить повторно используемые компоненты представления. Имея бурлящие события, они знают, когда и как обновить себя через AJAX!

Работа с виджетами Apotomo практически похоже на разработку компонентов GUI - в среде Rails.

Попробуй, это здорово.

2 голосов
/ 18 мая 2011

Лучшим решением (чем использование hidden_field) может быть проверка request.referer в действии вашего контроллера. Таким образом, вы используете тот факт, что каждый контекст имеет уникальный URL, и вам не нужно явно указывать другое уникальное значение при рендеринге вашего виджета частичным.

2 голосов
/ 18 мая 2011

Я бы не рекомендовал использовать UJS для приложений на стороне клиента: сервер не должен заниматься бизнесом на стороне клиента.Я согласен, что это полезно и чисто, но ему не хватает производительности, и поэтому его следует сохранить для бэкэнда (RJS перейдет в самоцвет, см. Здесь: http://weblog.rubyonrails.org/2011/4/21/jquery-new-default).

Тем не менее, вернемся к решениям, которые вы выставляете:

  • 1) Я думаю, вам не понадобится дополнительный контроллер, вам просто нужно будет передать дополнительные параметры, чтобы узнать, откуда поступил запрос.A hidden_field мог бы добиться цели.Имея эту информацию, просчитайте хороший js.erb файл

    format.js { if condition
                 render "create.js.erb"
                else
                  render "create_2.js.erb"
                end
              }
    
  • 2) Я бы пошел на это и вернул json, но вы столкнетесь с той же проблемой: зная, откудазапрос приходит от.

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