Angular js meetup


Published on

  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Angular js meetup

  1. 1. Building up withAngularJSdesign patterns for dealing with UIcomplexity.Greg Weber yap.TV
  2. 2. You chose AngularJS.Good job!A: Use plain-old JS object, dont need toinherit from a special base: that gives usgreater flexibility.Q: Why a good framework such as AngularJS?A: 2-way data-binding eases your pain.Q: Why AngularJS instead of other 2-way data-binding frameworks?Note: I am not saying that AngularJS is superior to all other frameworks or that it is the bestchoice for your team and your project.
  3. 3. Keeping Data up to date* AngularJS keeps the *view* up to date basedon the data in the controller.Problem: modularity demands differentcontrollers communicating via services.* What happens when a view uses data that ischanged in another view?
  4. 4. Growing complexity// in servicevar data = []changeData = =>$http(api).success (data) =>data = []return { data: data }// in first controller$ = in second controllerservice.changeData()Complexity Fail: the controller is referencing theoriginal data, doesnt know about new value// in controller$http(api).success (data) =>$ = data​Simplicy & Happiness Complexity & Sadness
  5. 5. (Overly) simple approach: placing data on the $rootScope and watching it ondifferent controllers.Problems: This could lead to a collision, and also in the case of an isolatedscope will not be propagated.var myModule = angular.module(myModule, []);myModule.factory(mySharedService, function($rootScope) {var sharedService = {};// expose service data to angular scope$rootScope.sharedData = = {}; = ;return sharedService;}); ControllerZero($scope, sharedService) {$scope.handleClick = function(msg) { = msg;};$scope.$watch(sharedData.message, function(msg) {$scope.message = msg;});}function ControllerOne($scope, sharedService) {$scope.$watch(sharedData.message, function() {$scope.message = ONE: +;});}
  6. 6. Using events events we can clearly communicate between controllers. And when we arecommunicating with code not integrated with angular, this is often the best approachProblem:● using fragile strings. Potential (unexplored) solution: use signals.js or use variablesthat contain the string names● Usage is a bit more obscure: we will likely end up broadcasting events to everycontroller whether they care about them or not. We will search for a string to find theevent source rather than looking for a service● Some boilerplate in the$rootScope) {$rootScope.$on(handleEmit, function(event, args) {$rootScope.$broadcast(handleBroadcast, args);});});function ControllerZero($scope) {$scope.handleClick = function(msg) {$scope.$emit(handleEmit, {message: msg});};}function ControllerOne($scope) {$scope.$on(handleBroadcast, function(event, args) {$scope.message = ONE: + args.message;});}
  7. 7. Communication via services: getters// in service$rootScope.on change, changeData$rootScope.broadcast(event, data)// in controller$scope.on(event, ...)// another controller$rootScope.broadcast(change, [])In AngularJS this can bechanged to a function call// in servicevar data = []return {changeData: => ...getData: => return data}// in controller, assign a function$ = service.getData// in view: ng-bind="data()"// could instead $watch the getter// another controllerservice.changeData([])Events
  8. 8. Communication via services: mutation// in servicevar data = []var changeData = =>$http(...).success (data) =>data.length = 0data.push(d) for d in datareturn {data: datachangeData: changeData}​// in controller$ =
  9. 9. Dealing with complexity: notAngularJS specific* complex data modeling with adt.js* managing complex UI State with statecharts
  10. 10. Data modeling with adt.jsFacebook feed =>Each Facebook feed item can be anentirely different kind of data:● picture● video● link share● status update● surveysOriginal code: mostly undefined/nullobject fields (single table inheritance),type is differentiated by a kind field. code: a DRY schema that does some dataconversion/validation, and it is clear what fields are actually supposedto exist. Our code is our documentation.A schema is just a key-pair of field name and a function that cancoerce the data (parseInt) or throw an exception.
  11. 11. Statecharts: dealing with complexitySolution: be very *explicit* about using state.Statecharts were created to manage the complexity of Jet Fighter software. The existing giantspecification still did not explain how everything interacted. Using statecharts they were able todocument the interaction and communicate it to non-engineers.Problem: Our UI has implicit state mutation:we switch from one view (state) to another. What transitions are valid? What should happen as statechanges? How do we handle concurrent states (different views at once, popups, etc)?
  12. 12. Statechart: alternatives* Just use routing. Problems: concurrent states,doing proper nested state transitions,remembering history of different branches.* Just use a FSM (multiple FSMs for concurrentstates). Problem: Nested states* Stativus library: full-featured, large code base,some bugs* A few other non-maintained/GPL libraries* Wrote my own StateChart implemenationinstead. It is smaller & levarages TypeScript.Will open source soon.
  13. 13. Statecharts: codestate.goTo()exit existing states & enter new state,calling all exit and enter callbacksexiting creates a history state that wecan go back (like a back button)exiting: authenticate history of rootentering loggedinlogged in & startingentering displayentering guideentering guide-Tuesdayexiting: guide-Tuesday history of guideexiting: guide history of displayentering showsentering favoritesentering myNewexiting: myNew history of favoritesexiting: favorites history of showsentering show-searchexiting: show-search history of showsexiting: shows history of displayentering guideentering guide-Tuesday