25
ARCHITECTURE, AUTH, AND ROUTING WITH UIROUTER chris caplinger [email protected] @unicode_snowman

Architecture, Auth, and Routing with uiRouter

Embed Size (px)

DESCRIPTION

My talk on uiRouter from the October ngNYC meetup. http://www.meetup.com/ng-nyc

Citation preview

Page 1: Architecture, Auth, and Routing with uiRouter

ARCHITECTURE, AUTH, AND ROUTING WITH UIROUTER

chris caplinger

[email protected]

@unicode_snowman

Page 2: Architecture, Auth, and Routing with uiRouter

WHAT IS UIROUTER?“AngularUI Router is a routing framework forAngularJS, which allows you to organize theparts of your interface into a state machine.

Unlike the $route service in the Angular ngRoutemodule, which is organized around URL routes,

UI-Router is organized around states, which mayoptionally be associated with URLs.”

Page 3: Architecture, Auth, and Routing with uiRouter

WHY A ROUTER IN GENERAL?Associates Routes/URLs with application state

i.e. views and their associated controllers and models

Page 4: Architecture, Auth, and Routing with uiRouter

“When we wrote the original router it was, to ourimagination, pretty cool... except it was vastlyinadequate for a large number of use cases.”

Page 5: Architecture, Auth, and Routing with uiRouter

NGROUTE SHORTCOMINGSonly one ngViewencourages ngShow/ngHide/ngIf/ngSwitch abusenested templates in nested templates in nested templates... in nested templates...

...overall, painful with larger apps

Page 6: Architecture, Auth, and Routing with uiRouter
Page 7: Architecture, Auth, and Routing with uiRouter

SO WHAT'S DIFFERENT ABOUT UIROUTER?

Page 8: Architecture, Auth, and Routing with uiRouter

STATE STATE STATE“...an abstract machine that can be in one of afinite number of states. The machine is in onlyone state at a time... It can transition from one

state to another by a triggering event orcondition; A particular FSM is defined by a list of

its states, and the triggering condition for eachtransition.”

Page 9: Architecture, Auth, and Routing with uiRouter

YOUR APP IS ALREADY STATEFUL!

Page 10: Architecture, Auth, and Routing with uiRouter

angular.module('MyApp').config(function ($stateProvider) { $stateProvider .state({ name: 'home', url: '/', templateUrl: '/where/is/my/home/template-ptl.html', controller: 'HomeController', resolve: { /* get some data! */ } }) .state({ name: 'items', url: '/items', templateUrl: '/where/is/my/template-ptl.html', controller: 'ItemsController', resolve: { items: function (Item) { return Item.all(); } } });});<!-- somewhere else, likely index.html --><ui-view></ui-view>

Page 11: Architecture, Auth, and Routing with uiRouter

$STATE// navigate to /home state$state.go('home')

// navigate to /items state$state.go('items')

Page 12: Architecture, Auth, and Routing with uiRouter

<a ui-sref="items">Check Out These Items</a>

Page 13: Architecture, Auth, and Routing with uiRouter

NESTED VIEWS$stateProvider .state({ name: 'items', url: '/items', // navigate to /items templateUrl: '/my/item/template-ptl.html', }) .state({ name: 'items.detail', url: '/:id', // navigate to /items/123 because items.detail is a child state of items templateUrl: 'my/item/detail/template-ptl.html', controller: 'ItemController', resolve: { item: function (Items, $stateParams) { return Items.find($stateParams.id); } } });

Page 14: Architecture, Auth, and Routing with uiRouter

<!-- index.html --><ui-view></ui-view>

<!-- my/item/template-ptl.html --><ui-view></ui-view>

Page 15: Architecture, Auth, and Routing with uiRouter

// get there with...$state.go('items.detail', { id: 123 });

// or relative...$state.go('.detail', { id: 123 });

<!-- or via a link... --><a ui-sref=".detail({ id: 123 })">Item 123</a>

Page 16: Architecture, Auth, and Routing with uiRouter

DEMO TIMESTEP-BY-STEP FLOW!

Page 17: Architecture, Auth, and Routing with uiRouter

NAMED VIEWS

Page 18: Architecture, Auth, and Routing with uiRouter

$stateProvider .state({ name: 'someParent', url: '/parent', views: { 'layoutA': { templateUrl: '/layout-a.html' }, 'content1@someParent': { templateUrl: 'content-1.html' }, 'content2@someParent': { templateUrl: 'content-2A.html' } } }) .state({ name: 'someParent.child', url: '/:id', views: { 'content2@someParent': { templateUrl: 'content-2B.html' } } });

<!-- index.html --><ui-view name="layoutA"></ui-view>

<!-- layout-a.html --><div> <ui-view name="content1"></ui-view></div><div> <ui-view name="content2"></ui-view></div>

Page 19: Architecture, Auth, and Routing with uiRouter

THE RETURN OF DEMOTIME

NAMED VIEWS!

Page 20: Architecture, Auth, and Routing with uiRouter

AUTHORIZATION AND REDIRECTION

Page 21: Architecture, Auth, and Routing with uiRouter

OBLIGATORY OBVIOUSTHING

CLIENT-SIDE AUTH AIN'T NO THINGserver side is where the magic happens

this is really about UX

Page 22: Architecture, Auth, and Routing with uiRouter

$STATECHANGE* EVENTSangular.app('MyApp').run(function ($rootScope, $state) { $rootScope.$on('$stateChangeError', function (e, toState, toParams, fromState, fromParams, error) if (error.status == 401) { $state.go('login'); } else { // other error types, 404, 500 // maybe a redirect, maybe not } });});

Page 23: Architecture, Auth, and Routing with uiRouter

angular.app('MyApp').run(function ($rootScope, $state, AuthService, User) { $rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams, error) { if (toState.data.checkAuth && !User.isAuthorized) { e.preventDefault();

AuthService.doAsyncThing().then(function (res) { $state.go(toState, toParams, { notify: false }).then(function () { $rootScope.$broadcast('$stateChangeSuccess', toState, toParams, fromState }); }).catch(function (err) { // do something here, redirect, or let your $stateChangeError handler catch the error }) } });});

Page 24: Architecture, Auth, and Routing with uiRouter

OTHER THOUGHTS ON REDIRECTIONdecorate $state.transitionTo for finer-grained control (a bit

hackier than I'd like, but it works)$stateChangeError redirection from navigating directly to a

URL, need to replace entry

Page 25: Architecture, Auth, and Routing with uiRouter

QUESTIONS, COMMENTS, CONCERNS?

chris caplinger

[email protected]

@unicode_snowman