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 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):
$state.go('data.update', {resourceName: resourceName, recordID: recordID}, {location: 'replace', reload: true});
...or by HTML links using fragment identifiers to encode the state reference:
<a href="#/data/update/{{resourceName}}/{{recordID}}">Edit Record</a>
Either variant would be resolved against this entry in www/config/routing.py
:
.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
<ion-nav-view>
directive on thewww/index.html
front-page withwww/views/data/update.html
(executing any directives) - invoke the
EMDataUpdate
controller (defined inwwww/controllers/update.js
) - pass the
resourceName
andrecordID
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:
<!-- in the view: --> <h1>{{title}}</h1>
...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):
// 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:
<!-- in the view: --> <input type="text" ng-model="firstName"/>
...can be accessed as:
// in the controller: var firstName = $scope.firstName;
Besides data, the $scope
object can also hold functions:
// in the controller: $scope.buttonClicked = function() { // Do something };
...which can then e.g. be used in the view as event handlers:
<!-- in the view --> <button type="button" ng-click="buttonClicked()"/>
State controllers live in the www/controllers folder, and view templates in www/views.