Вызов функции перед рендером - PullRequest
2 голосов
/ 10 августа 2011

Я хотел бы заменять набор div каждый раз, когда я получаю запрос ajax (веб-сайт, над которым я работаю, заполнен ajax ...).Например, это может быть проверка количества сообщений в почтовом ящике или отображение статистики пользователя ...

Дело в том, что я не хочу повторять этот вызов моей функции рендеринга много раз в моемcode.

Я пытался вызвать свою функцию в before_filter, но так как я вызываю render: update, он не работает во второй раз.

Я пытался создать свою собственную функцию render_page в application_controller:

def render_page
  render :update do |page|
    yield(page)
    # page.replace_html :div, ...
  end
end

Но каким-то образом контекст кажется потерянным: когда я вызываю render_page для функции контроллера, я не могу получить доступ к вспомогательным функциям ...

Спасибо!

1 Ответ

2 голосов
/ 17 августа 2011

Нашел!

Я немного покопался в документации по ruby ​​on rails, чтобы узнать, как работает функция render: update.

Сначала я увидел, что render: update просто вызывалupdate_page путем отправки блока кода ...

http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#method-i-update_page

И эта функция вызывает конструктор JavaScriptGenerator, отправляя view_context (который является просто экземпляром ActionView :: Base).

JavaScriptGenerator.new(view_context, &block).to_s.html_safe

http://apidock.com/rails/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/new/class

И в конструкторе JavaScriptGenerator мы можем наблюдать

def initialize(context, &block) #:nodoc:
  @context, @lines = context, []
  include_helpers_from_context
  @context.with_output_buffer(@lines) do
    @context.instance_exec(self, &block)
  end
end

instance_exec - это функция ruby, которая позволяет вызывать блок в контексте... Это было именно то, что мне было нужно.

Итак, решение (или хотя бы одно рабочее решение ...) заключается в определении render_page в application_controller:

def render_page(&block)
  render :update do |page|
    page << 'console.log("before_code");'
    self.instance_exec(page, &block)
    page << 'console.log("after_code");'
  end
end

Таким образом, вместо вызова в моих контроллерах

render :update do |page|
  page.replace_html ...
  helper_functions...
end

я вызываю

render_page do |page|
  page.replace_html ...
  helper_functions...
end

И мне все еще разрешено вызывать мои вспомогательные функции (так как контекст был передан)...

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