Skip to content

Instantly share code, notes, and snippets.

@mikew
Last active January 2, 2016 18:59
Show Gist options
  • Save mikew/8347505 to your computer and use it in GitHub Desktop.
Save mikew/8347505 to your computer and use it in GitHub Desktop.
Of ui-router and controllers

This is really just a shorthand for:

  • Creating an Angular controller using standard object notation.
  • Less repetition, but full support, of dependencies.
  • Support either Controller as resource, or passing it off to a separate view.
  • Creating States for ui-route, with all of the above.

What I like about this combined with ui-route is the pattern for resources:

var UIView = require('base/uiview');
var BaseController = require('base/controllers');
require('resource/services');

var base = {
  abstract: true,

  // The name for inheritance
  name: 'resource',

  // The base URL for the views
  url: 'resource',

  // Inherit from the very base controller.
  parent: BaseController.base,
  template: '<ui-view></ui-view>'
};

var list = UIView.extend({
  url: '',
  name: 'resource.list',
  define: 'ResourceList',
  as: 'resource',
  parent: base,
  templateUrl: 'partials/resource/list.html',
  // Since we are injecting the Simulations Service
  // (combined with UIView.extend and `Controller as` syntax),
  // the template gets access to `this.ResourceService` automatically.
  //template: '<div ng-repeat="obj in resource.ResourceService.all()">{{ obj.title }}</div>',
  inject: ['$scope', 'ResourceService']
});

var details = UIView.extend({
  url: '/:id',
  name: 'resource.details',
  define: 'ResourceDetails',
  as: 'resource',
  parent: base,
  templateUrl: 'partials/resource/details.html',
  inject: ['$scope', '$stateParams', 'ResourceService'],

  initialize: function () {
    this.obj = this.ResourceService.get(this.$stateParams.id);
  }
});

module.exports.base = base;
module.exports.list = list;
module.exports.details = details;
var UIView = require('base/uiview');
var template = "<div>\n <span>{{todos.remaining()}} of {{todos.list.length}} remaining</span>\n [<a href=\"\" ng-click=\"todos.archive()\">archive</a>]\n <ul>\n <li ng-repeat=\"todo in todos.list\">\n <input type=\"checkbox\" ng-model=\"todo.done\">\n <span class=\"done-{{todo.done}}\">{{todo.text}}</span>\n </li>\n </ul>\n <form ng-submit=\"todos.addTodo()\">\n <input type=\"text\" ng-model=\"todos.input\" placeholder=\"add a new todo\">\n <input type=\"submit\" value=\"add\">\n </form>\n</div>",
var TodoIndex = UIView.build_controller({
// Accepts regular state / route properties
url: '/todos',
name: 'todos',
template: template,
// And a couple of more for extra functionality
define: 'TodoController',
as: 'todos',
// You can inject things. If you leave it blank you still get `$state`
// That `*` will add that variable to the `$state` and the controller
// instance. Otherwise, anything listed here just gets added to the
// controller instance. Resolvers can be added here as well
//inject: ['$state', 'userservice*']
// Any other properties / methods are added to the instance where
// you can use `this.` safely.
list: [
{
text: 'learn angular',
done: false
}
],
addTodo: function () {
this.list.push({text: this.input, done: false});
this.input = '';
},
remaining: function () {
var count = 0;
for (var i = 0; i < this.list.length; i++) {
var todo = this.list[i];
count += todo.done ? 0 : 1;
}
return count;
},
archive: function () {
var oldList = this.list;
this.list = [];
for (var i = 0; i < oldList.length; i++) {
var todo = oldList[i];
if (!todo.done) {
this.list.push(todo);
}
}
}
});
application.config([
'$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state(TodoState);
}
]);
var UIView = require('base/uiview')
var index = UIView.build_controller({
name: 'TodoIndexController',
register: true,
list: [
{
text: 'learn angular',
done: false
}
],
addTodo: function () {
this.list.push({text: this.input, done: false});
this.input = '';
},
remaining: function () {
var count = 0;
for (var i = 0; i < this.list.length; i++) {
var todo = this.list[i];
count += todo.done ? 0 : 1;
}
return count;
},
archive: function () {
var oldList = this.list;
this.list = [];
for (var i = 0; i < oldList.length; i++) {
var todo = oldList[i];
if (!todo.done) {
this.list.push(todo);
}
}
}
});
var TodoViews = require('todo-views');
application.config([
'$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state(TodoViews.index);
}
]);
var UIView = require('base/uiview')
var Controllers = require('todo-controllers');
var template = "<div>\n <span>{{todos.remaining()}} of {{todos.list.length}} remaining</span>\n [<a href=\"\" ng-click=\"todos.archive()\">archive</a>]\n <ul>\n <li ng-repeat=\"todo in todos.list\">\n <input type=\"checkbox\" ng-model=\"todo.done\">\n <span class=\"done-{{todo.done}}\">{{todo.text}}</span>\n </li>\n </ul>\n <form ng-submit=\"todos.addTodo()\">\n <input type=\"text\" ng-model=\"todos.input\" placeholder=\"add a new todo\">\n <input type=\"submit\" value=\"add\">\n </form>\n</div>",
var index = UIView.extend({
url: '/todos',
name: 'todos',
template: template,
controller: Controllers.index,
as: 'todos'
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment