= EdenMobile UI Routing and Controllers =
EdenMobile is a single-page application (SPA), i.e. it only has a single page {{{www/index.html}}} which is loaded when the app starts, and has parts of its contents replaced as the user interacts with it.
Instead of "pages" to display different application views, EdenMobile implements application '''states'''. Each state has its own "view template" that defines the inner HTML of the front-page, and a controller that supplies data and processing methods for the UI widgets.
== Routing ==
The routing of user actions to the different app states is provided by the [https://github.com/angular-ui/ui-router/wiki AngularJS UI Router].
States have names to reference them, and state references can additionally contain parameters to pass to the state controller.
States can be entered either by using {{{$state.go()}}} (=similar to Sahana Eden's {{{redirect()}}}, just without leaving the page):
{{{#!js
$state.go('data.update', {resourceName: resourceName, recordID: recordID}, {location: 'replace', reload: true});
}}}
...or by HTML links using fragment identifiers to encode the state reference:
{{{#!xml
Edit Record
}}}
Either variant would be resolved against this entry in {{{www/config/routing.py}}}:
{{{#!js
.state('data.update', {
url: '/{resourceName}/{recordID:int}',
views: {
'data': {
templateUrl: 'views/data/update.html',
controller: "EMDataUpdate"
}
}
})
}}}
...and let the UI router:
- replace the contents of the {{{}}} directive on the {{{www/index.html}}} front-page with {{{www/views/data/update.html}}} (executing any directives)
- invoke the {{{EMDataUpdate}}} controller (defined in {{{wwww/controllers/update.js}}})
- pass the {{{resourceName}}} and {{{recordID}}} parameters to the {{{$stateParams}}}, from where the controller can access them
== View and Controller ==
The role of controllers and views is equivalent to controllers/views in the Sahana Eden web application. The view template is rendered, and the state controller executed, when the state is first entered (unless reloading is enforced in $state.go, then both would be reloaded).
View and controller in EdenMobile are connected through the AngularJS "model" (=a data object in memory similar to Sahana Eden's ''response''). Access to the "model" is provided by the {{{$scope}}} service, which is why we commonly refer to it as the '''Scope''' rather than the "Model" (also to avoid confusion with database table schemas which are called "models" in Sahana Eden).
Note, however, that the scope is not a singleton like ''response'': scopes are hierarchical, and usually upwards-transparent (although they can be fully isolated).
And unlike Sahana Eden ''responses'', placeholders in EdenMobile views are ''updated'' whenever the corresponding {{{$scope}}} attribute changes, e.g. a template like:
{{{#!xml
{{title}}
}}}
...would replace the ''title'' placeholder with the value of {{{$scope.title}}}, similar to Sahana Eden views. But when the controller later changes {{{$scope.title}}} (e.g. in response to an event):
{{{#!js
// in the controller:
$scope.title = 'Something Else';
}}}
...then this will also update the view (instantly, more or less).
Equally, view elements (e.g. inputs) can be bound to {{{$scope}}} attributes (using the {{{ng-model}}} directive), so that every change of the input value will be reflected instantly in the {{{$scope}}}, thereby making it available for the controller:
{{{#!xml
}}}
...can be accessed as:
{{{#!js
// in the controller:
var firstName = $scope.firstName;
}}}
Besides data, the {{{$scope}}} object can also hold functions:
{{{#!js
// in the controller:
$scope.buttonClicked = function() {
// Do something
};
}}}
...which can then e.g. be used in the view as event handlers:
{{{#!xml
}}}
State controllers live in the www/controllers folder, and view templates in www/views.