Skip to content
Maksim Ovcharik edited this page Dec 12, 2016 · 2 revisions

Этапы работы контроллера

После получения http запроса сервер отдает его (условно) в роутер. В роутере срабатывает метод route, который начинает обрабатывать запрос, а именно метод в списке путей ищет объект, который соответствует данному пути и методу. Далее на основе полученного объекта выбирается контроллер, который будет обрабатывать запрос и создается его инстанция.

В конструктор контроллера передаются request, response и имя действия взятое из списка путей.

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

После, в конструкторе запускается метод формирования ответа.

Формирования ответа

Во время формирования ответа сначала отрабатывают before фильтры, потом сам метод обрабатывающий запрос и after фильтры.

Фильтры

class ExampleController extends BaseController
  @beforeFilter 'filter1'
  @beforeFilter 'filter2', { only: => ['index'] }
  
  index: ->
    ...
  filter1: ->
  filter2: ->

Для действия index сначала отработает filter1, за ним filter2, а уже только после этого будет вызван сам метод индекс.

@beforeFilter methodName[, options]

  • methodName - строка с названием метода фильтра
  • options - объект, с помощью которого можно определить поведение фильтра. По умолчанию фильтры работают для всех событий.
    • only - массив действий перед которыми будет работать фильтр
    • except - массив действий перед которыми не будет работать фильтр

afterFilter - работает аналогично beforeFilter, только отрабатывает после основного действия.

Асинхронность

При вызове некоторых методов, например запросы в бд, в функцию нужно передать callback. Колбек будет работать (условно) в другом потоке, а функция запроса завершиться сразу же. Таким образом может возникнуть ситуация, когда данные еще не получены а метод уже фильтра или основного действия уже отработал и после него будет вызван следующий метод, хотя не должен.

Что бы избежать такой ситуации, методы фильтра или действия должны вернуть false, в этом случае поток выполнения будет остановлен, и что бы его восстановить, необходимо вызвать @next().

ApplicationHelper =
  
  findCurrentUser: ->
    if @request.cookies.email and @request.cookies.password
      user = {
        email: @request.cookies.email
        password: @request.cookies.password
      }
      User.findOne user, (err, user) =>
        @setCurrentUser user if not err and user
        @next()
      return false
    return true

Данный хелпер подключается в ApplicationController, а метод findCurrentUser в ApplicationController'е передается в beforeFilter. В методе если нужен запрос к бд, то сам метод вернет false, что остановит поток выполнения, а восстановится он только после запуска функции next в колбеке, если запрос не нужен, то посылается true и выполнение продолжится автоматически.

Ответ по умолчанию

Если в действии не был сформирован ответ для пользователя, то вызовется метод render.

Данный метод попытается отрендерить файл в папке views по следующему пути: [controller_name]/[action].jade.

class HomeController extends ApplicationController
  
  index: ->
    @title = "Home"
    return true

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

Свойства

В контроллере унаследованном от BaseController доступны следующие свойства:

  • @action - название действия
  • @request - объект запроса
  • @response - объект ответа

Clone this wiki locally