Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ngPittsburgh - AngularUI Router Philosophy

Nate Abele
September 16, 2015

ngPittsburgh - AngularUI Router Philosophy

Talk given at ngPittsburgh on September 16th, 2015 about the philosophy and future of AngularUI Router.

Nate Abele

September 16, 2015
Tweet

More Decks by Nate Abele

Other Decks in Technology

Transcript

  1. Basically a Vanity Slide Former lead dev, CakePHP Founder, Li3

    (aka Lithium) Member, AngularUI Team Founding Member / Lead Dev, UI Router Architect, Radify @nateabele [email protected]
  2. AngularUI What? AngularUI Router is a state machine that coordinates

    user interface rendering, data flow, and URL synchronization, as a user navigates through a system.
  3. State Machine? “[A] mathematical model of computation used to design

    both computer programs and sequential logic circuits. It is conceived as an abstract machine that can be in one of a finite number of states.” — Wikipedia: Finite-state machine
  4. “The main reason for using state machines is to help

    the design process. It is much easier to figure out all the possible edge conditions by drawing out the state machine on paper. This will make sure that your application will have less bugs and less undefined behavior.” State Machine?
  5. “Moreover, state machines have decades of math and CS research

    behind them about analyzing them, simplifying them, and much more. Once you realize that in management state machines are called business processes, you'll find a wealth of information and tools at your disposal.” https://www.shopify.com/technology/3383012-why-developers-should-be-force-fed-state-machines State Machine?
  6. Component Router $router.config([ { path: '/', redirectTo: '/home' }, {

    path: '/home', component: 'home' }, { path: '/users', component: 'users' } ]);
  7. $rootScope.$on('$stateChangeStart', (e, toState) => { if (toState.data.authorization && !user.isLoggedIn()) {

    e.preventDefault(); $state.go("login"); } if (toState.data.admin && !user.isAdmin()) { // ... } // ... });
  8. Hook Values true: transition allowed false: transition rejected { …

    }: new resolve values Promise<*>: Any value can be promise-wrapped
  9. $transitionsProvider.onStart({ to: state => !!state.data.requiresAuth }, (user, $state, $transition$) =>

    { return ( user.isLoggedIn() || $state.redirect($transition$).to('user.login') ); });
  10. The Transition Object $transition.to(): the target state $transition.from(): the origin

    state $transition.params(): target state parameters $transition.options(): passed transition options
  11. The Transition Object $transition.entering(): states being entered $transition.exiting(): states being

    exited $transition.retained(): states retained $transition.views(): view configs for changed states
  12. export default class Location { constructor( public lat: number, public

    lon: number, public zoom: number ) {} toString() { return [this.lat, this.lon, this.zoom].join(",") + "z" } }
  13. $urlMatcherFactoryProvider.type("Location", { encode(loc) { return “@" + loc; } decode(str)

    { return new Location( ...str.match(this.pattern).slice(1) ); }, pattern: /@(-?\d+\.\d+),(-?\d+\.\d+),(\d+)z/ });
  14. class MapController { constructor($scope, $stateParams) { // Expose for binding

    to maps directive $scope.location = $stateParams.location; // Changes to map will auto-propagate to URL $stateParams.$observe("location", () => { ... }) } }