Chaplin.Controller → Source

Controllers are in charge of handling the lifecycle of specific models and their associated views. That is, they are responsible for both instantiating and connecting models/collections and their views, as well as disposing of them, before handing control over to another controller. There can be only one current controller, which provides the main view and represents the current URL. In addition, there can be several persistent controllers for overarching tasks, like for example a SessionController.

Methods

adjustTitle(subtitle)

Adjusts document title to subtitle - title. A title template can be set when initializing the Dispatcher.

redirectTo(params, options)

Simple proxy to Chaplin.utils.redirectTo that also does this.redirected = true;. See Chaplin.utils.redirectTo for details.

dispose()

Disposes all models and views on current Controller instance.

Usage

Structure

By convention, there is one controller for each application module. A controller may provide methods for several actions like index, show, edit, etc. These action methods are called by the Chaplin.Dispatcher when an associated route matches.

A controller is usually started following a route match. Each route entry points to one controller action, for example likes#show, which is the show action of the LikesController.

Naming convention

By default, all controllers must be placed in the /controllers/ folder (the / stands for the root of the baseURL you have defined for your loader) and be suffixed with _controller. So for instance, the LikesController needs to be defined in the file /controllers/likes_controller.js.

If you want to overwrite this behaviour, you can edit the controller_path and controller_suffix options in the options hash you pass to Chaplin.Application.initDispatcher or Chaplin.Dispatcher.initialize. See details in the Chaplin.Dispatcher documentation.

Before actions

To execute code before the controller action is called, you can define a handler as the beforeAction property (e.g. to add access control checks).

Example

define [
  'controllers/controller',
  'models/likes',          # the collection
  'models/like',           # the model
  'views/likes-view',      # the collection view
  'views/full-like-view'   # the view
], (Controller, Likes, Like, LikesView, FullLikeView) ->
  'use strict'

  class LikesController extends Controller
    beforeAction: (params, route) ->
      if route.action is 'show'
        @redirectUnlessLoggedIn()

    # Initialize method is empty here.
    index: (params) ->
      @collection = new Likes()
      @view = new LikesView {@collection}

    show: (params) ->
      @model = new Like id: params.id
      @view = new FullLikeView {@model}
define([
  'controllers/controller',
  'models/likes',          // the collection
  'models/like',           // the model
  'views/likes-view',      // the collection view
  'views/full-like-view'   // the view
], function(Controller, Likes, Like, LikesView, FullLikeView) {
  'use strict'

  var LikesController = Controller.extend({
    beforeAction: function() {
      this.redirectUnlessLoggedIn();
    },

    // Initialize method is empty here.
    index: function(params) {
      this.collection = new Likes();
      this.view = new LikesView({collection: this.collection});
    },

    show: function(params) {
      this.model = new Like({id: params.id});
      this.view = new FullLikeView({model: this.model});
    }
  });
  return LikesController;
});

Creating models and views

A controller action should create a main view and save it as an instance property named view: this.view = new SomeView(…).

Normal models and collections should also be saved as instance properties so Chaplin can reach them.

Controller disposal and object persistence

By default a new controller is instantiated with every route match. That means models and views are disposed by default, even if the new controller is the same as the old controller.

To persist models and views in a controlled way, it is recommended to use the Chaplin.Composer.

Chaplin will automatically dispose all models and views that are properties of the controller instance. If you’re using the Composer to reuse models and views, you need to use local variables instead of controller properties. Otherwise Chaplin will dispose them with the controller.

Including Controllers in the production build

In your production environment, you may want to package your files together using a build tool like r.js.

Controllers are dynamically loaded from the Chaplin.Dispatcher using the require() method. Build tools like r.js can’t know about files that are lazy-loaded using require(). They only consider the static dependencies specified by define().

This means that build tools will ignore your controllers and won’t include them in your package. You need to include them manually, for instance with r.js:

paths:
  # ...
modules:
  - name: 'application'
  - name: 'controllers/one_controller'       # included manually into the build
  - name: 'controllers/another_controller'   # same