Skip to content

Controllers and Routing

mike edited this page Apr 26, 2020 · 5 revisions

On this page:

1 Routing

2 Controllers

3 Guard methods

4 Around filters

5 Data

6 Wrappers

Before reading, let's see small example:

"route-part":   (ev) ->
    ^             ^      
  path       controller action

And first all about route-part

routing

The main method of application. From routing usually starts all flows in the application. A route is an event in a browser, like a click. The route is a timer, like a setTimeout. The route is an URL change.

event routing

Any event may be a part of the route:

click #my-element  
keyup body 
dblclick .my-button 
click li input[type='text']

As you can see, a common rule for event routing is the first event name, second element selector (class, id, or tag).

"click: #my-element"
   ^        ^
  event   selector  

custom event routing

Custom events defined as

application:run

my-custom-event-name:boom

Pretty simple, right?

timers

If you want to run some actions (function) periodically or only once, after some time, then you should use this kind of routing, rule:

timer-keyword wait-time-unit time-unit   

1 timer-keyword is

1.1 once - run only once, setTimeout

1.2 every - run every time-unit setInterval

1.3 scheduler - alias for every

  1. wait-time-unit is time before action will be called. Number + time unit, time unit is: m for minutes, s for seconds, and ms for milliseconds

  2. time-unit - is time for run action.

Examples:

every 1m - run action every 1 minute
once 1m - run with timeout 1 minute
every 1m 10s - run action every 10 seconds, before the first run wait 1 minute

URL changes

Url changes are of two kinds.

/plain-route
#/hash-route

Sirius support url parts:

/book/:id 
/book/[0-9]+
/books/:param1/:param2
/books/*

all this parts :id, [0-9]+, :param1, :param2 will be passed in controller. For example /book/:id match url /book/my-id, and my-id will be passed in controller. /book/[0-9]+ match url /book/123, and 123 will be passed in controller, /books/* matched url /books/123/asd/uuid, and [123, asd, uuid] will be passed in controller.

This is all about routing.

controllers

A controller in Sirius is function or object with functions.

"click button": (ev) -> 
                   ^
                controller is a function

"click button": { controller: MyController, action: "on_click_action" } 
                                ^                         ^
                             object         with      function


# and definition like

MyController =
  on_click_action: (ev) -> 
    console.log("click :)")

guards methods

Sometimes, we need call actions, only if some condition is performed. For this Sirius have guard methods for routing:

For example, run action only if user click some button:

"keyup body" : {controller: MyController, action: "my_action", guard: my_guard_method}
                                                                 ^
                                                                this 

MyController = 
  my_guard_method: (ev) ->
    ev.keyCode == MY_KYE_CODE
        

And now, my_actions will be called, only if my_guard_method return true, otherwise, the method will be ignored.

around filters

If you want to call some callback before action or after, use around filters

"click button": {controller: MyController, action: "my_action", before: "run_before", after: "run_after"}

And now, before my_action and after my_action, Sirius will be called around filters

Control flow: click -> run_before -> my_action -> run_after

data

Usually you need get some data from target element on some event, for this you can use data:

<div id="my-element" data-id="123", data-name="example">click me</div>

"click #my-element": {controller: MyController, action: "click", data: ["data-id", "data-name"]}

MyController =
  click: (ev, id, name) -> 
    console.log(id)    # => 123
    console.log(name)  # => example

On click event, all necessary information will be passed to a controller action.

wrappers

Loggers, or another helped methods (ajax, conversion), always used in controllers. How to easily share it between controllers?

ControllerWrapper = 
  ajax: new MyAjaxServiceInstance()
  localStorageDao: new LocalStorageDao()
  someService: new MyService()

# then

Sirius.Application.run
  controller_wrapper: ControllerWrapper

# and now, in any controller action:
# instead of ControllerWrapper.ajax or something like this, you can use

MyController =
  my_action: () ->
   ajax.get_posts()
   localStorageDao.get_posts()
   someService.get_posts()