AngularJS in one day

B56bb22b3a4b83c6b534b4c114671380?s=47 Todd Motto
October 27, 2013

AngularJS in one day

Slides at a half-day workshop I gave at Google, San Francisco.

B56bb22b3a4b83c6b534b4c114671380?s=128

Todd Motto

October 27, 2013
Tweet

Transcript

  1. ANGULARJS CLIENT-SIDE MVC/MVVM JAVASCRIPT FRAMEWORK by @toddmotto

  2. KEY CONCEPTS Model View Controller Two way data-binding

  3. MODEL APPLICATION DATA STRUCTURE, ANY ABSTRACTIONS

  4. VIEW RENDERED HTML/COMPONENTS/TEMPLATES

  5. CONTROLLER COMMS WITH THE SERVER AND CLIENT

  6. TWO WAY DATA-BINDING KEEPING DATA IN SYNC, MODEL SPEAKS TO

    THE VIEW, VICE VERSA
  7. SETUP ESSENTIALS (HTML) < d i v n g -

    a p p = " m y A p p " > < d i v n g - c o n t r o l l e r = " M a i n C t r l " > < ! - - c o n t r o l l e r l o g i c - - > < / d i v > < / d i v >
  8. SETUP ESSENTIALS (JAVASCRIPT) v a r m y A p

    p = a n g u l a r . m o d u l e ( ' m y A p p ' , [ ] ) ; m y A p p . c o n t r o l l e r ( ' M a i n C t r l ' , [ ' $ s c o p e ' , f u n c t i o n ( $ s c o p e ) { / / C o n t r o l l e r l o g i c } ] ) ;
  9. CONTROLLERS: PUSHING TO THE $SCOPE (HTML) < d i v

    n g - a p p = " m y A p p " > < d i v n g - c o n t r o l l e r = " M a i n C t r l " > { { t e x t } } < / d i v > < / d i v >
  10. CONTROLLERS: PUSHING TO THE $SCOPE (JAVASCRIPT) v a r m

    y A p p = a n g u l a r . m o d u l e ( ' m y A p p ' , [ ] ) ; m y A p p . c o n t r o l l e r ( ' M a i n C t r l ' , [ ' $ s c o p e ' , f u n c t i o n ( $ s c o p e ) { $ s c o p e . t e x t = ' H e l l o , A n g u l a r f a n a t i c . ' ; } ] ) ;
  11. CONTROLLERS: PUSHING TO THE $SCOPE (OUTPUT) < d i v

    n g - a p p = " m y A p p " > < d i v n g - c o n t r o l l e r = " M a i n C t r l " > H e l l o , A n g u l a r f a n a t i c . < / d i v > < / d i v >
  12. DIRECTIVES: MANIPULATING THE DOM Reusable chunks of code injected Packaged

    and managed individually Custom buttons, forms, tooltips (components)
  13. DIRECTIVES: DOM DECLARATIONS < ! - - 1 : a

    s a n a t t r i b u t e d e c l a r a t i o n - - > < a c u s t o m - b u t t o n > C l i c k m e < / a > < ! - - 2 : a s a c u s t o m e l e m e n t - - > < c u s t o m - b u t t o n > C l i c k m e < / c u s t o m - b u t t o n > < ! - - 3 : a s a c l a s s ( u s e d f o r o l d I E c o m p a t ) - - > < a c l a s s = " c u s t o m - b u t t o n " > C l i c k m e < / a > < ! - - 4 : a s a c o m m e n t - - > < ! - - d i r e c t i v e : c u s t o m - b u t t o n - - >
  14. DIRECTIVES: JAVASCRIPT SETUP m y A p p . d

    i r e c t i v e ( ' c u s t o m B u t t o n ' , f u n c t i o n ( ) { r e t u r n { r e s t r i c t : ' A ' , r e p l a c e : t r u e , t r a n s c l u d e : t r u e , t e m p l a t e : ' < a h r e f = " " c l a s s = " c - b u t t o n " n g - t r a n s c l u d e > ' + ' < i c l a s s = " i c o n - o k - s i g n " > < / i > ' + ' < / a > ' , l i n k : f u n c t i o n ( s c o p e , e l e m e n t , a t t r s ) { / / D O M m a n i p u l a t i o n / e v e n t s h e r e ! } } ; } ) ;
  15. DIRECTIVES: DEFINITIONS restrict: usage, Attribute/Element/etc. replace: replaces declarative node transclude:

    Inject existing DOM (text) inside template: Markup, either <script> or ext .html file link: Events, custom manipulation
  16. SERVICES Singleton functions, more 'static'

  17. SERVICES: STATIC USE CASE m y A p p .

    s e r v i c e ( ' M a t h ' , f u n c t i o n ( ) { t h i s . m u l t i p l y = f u n c t i o n ( x , y ) { r e t u r n x * y ; } ; } ) ;
  18. FACTORY Model abstractions, application toolkits

  19. FACTORY: MODEL ABSTRACTION m y A p p . f

    a c t o r y ( ' J S O N F a c t o r y ' , [ ' $ h t t p ' , f u n c t i o n ( $ h t t p ) { v a r J S O N F a c t o r y = { g e t U s e r s : f u n c t i o n ( c a l l b a c k ) { $ h t t p . g e t ( ' / u s e r s ' ) . s u c c e s s ( c a l l b a c k ) ; } , p o s t U s e r s : f u n c t i o n ( c a l l b a c k ) { $ h t t p . p o s t ( ' / u s e r s U p d a t e ' ) . s u c c e s s ( c a l l b a c k ) ; } } ; r e t u r n J S O N F a c t o r y ; } ] ) ;
  20. FACTORY: DRY USAGE (EVERYWHERE!) / / d e p e

    n d e n c y i n j e c t m y A p p . c o n t r o l l e r ( ' M a i n C t r l ' , f u n c t i o n ( $ s c o p e , J S O N F a c t o r y ) { J S O N F a c t o r y . g e t U s e r s ( f u n c t i o n ( d a t a ) { $ s c o p e . u s e r s = d a t a ; / / o b j } ) ; } ] ) ;
  21. FILTERS Managing your data Single filtering (non-loop) Repeat filtering (loop)

    Multiple ways to create
  22. FILTERS: MANAGING YOUR DATA m y A p p .

    f i l t e r ( ' r e v e r s e ' , f u n c t i o n ( ) { r e t u r n f u n c t i o n ( i n p u t ) { v a r o u t = ' ' ; f o r ( v a r i = 0 ; i < i n p u t . l e n g t h ; i + + ) { o u t = i n p u t . c h a r A t ( i ) + o u t ; } r e t u r n o u t ; } } ) ;
  23. FILTERS: $SCOPE AS USUAL m y A p p .

    c o n t r o l l e r ( ' M a i n C t r l ' , [ ' $ s c o p e ' , f u n c t i o n ( $ s c o p e ) { $ s c o p e . g r e e t i n g = ' T o d d M o t t o ' ; } ] ) ;
  24. FILTERS: DECLARE (SINGLE, NO LOOP) < d i v n

    g - a p p = " m y A p p " > < d i v n g - c o n t r o l l e r = " M a i n C t r l " > < p > N o f i l t e r : { { g r e e t i n g } } < / p > < p > R e v e r s e : { { g r e e t i n g | r e v e r s e } } < / p > < / d i v > < / d i v >
  25. FILTERS: DECLARE (REPEAT, LOOP) < d i v n g

    - a p p = " m y A p p " > < u l n g - c o n t r o l l e r = " M a i n C t r l " > < l i n g - r e p e a t = " g r e e t i n g r e e t i n g s " > { { g r e e t | r e v e r s e } } < / l i > < / u l > < / d i v >
  26. CREATING YOUR FIRST APP Design: JSON design for best response

    Distribute: Integrate data w/Factory + Controllers Declare: Push to the $scope
  27. APP: DESIGN Design w/static data then replicate with backend endpoints

    / / i d e a l j s o n r e s p o n s e f r o m $ h t t p . g e t ( ) [ { " f r o m " : " S t e v e J o b s " , " s u b j e c t " : " I t h i n k I ' m h o l d i n g m y p h o n e w r o n g : / " , " s e n t " : " 2 0 1 3 - 1 0 - 0 1 T 0 8 : 0 5 : 5 9 Z " } , { " f r o m " : " E l l i e G o u l d i n g " , " s u b j e c t " : " I ' v e g o t S t a r r y E y e s , l u l z " , " s e n t " : " 2 0 1 3 - 0 9 - 2 1 T 1 9 : 4 5 : 0 0 Z " } , { " f r o m " : " M i c h a e l S t i p e " , " s u b j e c t " : " E v e r y b o d y h u r t s , s o m e t i m e s . " , " s e n t " : " 2 0 1 3 - 0 9 - 1 2 T 1 1 : 3 8 : 3 0 Z " } , { " f r o m " : " J e r e m y C l a r k s o n " , " s u b j e c t " : " T h i n k I ' v e f o u n d t h e b e s t c a r . . . I n t h e w o r l d " , " s e n t " : " 2 0 1 3 - 0 9 - 0 3 T 1 3 : 1 5 : 1 1 Z "
  28. APP: DISTRIBUTE (FACTORY CREATION) m y A p p .

    f a c t o r y ( ' J S O N F a c t o r y ' , [ ' $ h t t p ' , f u n c t i o n ( $ h t t p ) { v a r J S O N F a c t o r y = { g e t E m a i l s : f u n c t i o n ( c a l l b a c k ) { $ h t t p . g e t ( ' / u s e r s ' ) . s u c c e s s ( c a l l b a c k ) ; } , p o s t E m a i l C h a n g e s : f u n c t i o n ( c a l l b a c k ) { $ h t t p . p o s t ( ' / e m a i l U p d a t e s ' ) . s u c c e s s ( c a l l b a c k ) ; } } ; r e t u r n J S O N F a c t o r y ; } ] ) ;
  29. APP: DISTRIBUTE (CONTROLLER INJECTION) m y A p p .

    c o n t r o l l e r ( ' E m a i l C t r l ' , f u n c t i o n ( $ s c o p e , J S O N F a c t o r y ) { $ s c o p e . e m a i l s = { } ; / / n a m e s p a c e f o r d o m c l a r i t y J S O N F a c t o r y . g e t E m a i l s ( f u n c t i o n ( d a t a ) { $ s c o p e . e m a i l s . m e s s a g e s = d a t a ; / / r i d e o f f n / s } ) ; } ] ) ;
  30. APP: DECLARE < d i v n g - a

    p p = " m y A p p " > < u l n g - c o n t r o l l e r = " M a i n C t r l " > < l i n g - r e p e a t = " m e s s a g e i n e m a i l s . m e s s a g e " > F r o m : { { m e s s a g e . f r o m } } S u b j e c t : { { m e s s a g e . s u b j e c t } } { { m e s s a g e . s e n t | d a t e : ' M M M d , y h : m m : s s a ' } } < / l i > < / u l > < / d i v >
  31. CORE FUNCTIONS ng-* attrs (internal directives)

  32. CORE: NG-CLICK Scoped inline functions with access to elems, index,

    more < a n g - c l i c k = " d e l e t e E m a i l ( $ i n d e x ) " > D e l e t e e m a i l < / a >
  33. CORE: NG-MODEL Instantly reflected in the View + Model <

    i n p u t n g - m o d e l = " s e a r c h T e x t " >
  34. CORE: NG-VIEW Injecting dynamic views < d i v n

    g - v i e w > < / d i v >
  35. CORE: NG-SUBMIT Ajax form handling < f o r m

    n g - s u b m i t = " d o A w e s o m e A j a x ( ) ; " > < / f o r m >
  36. CORE: NG-DISABLED Form elements validation < b u t t

    o n t y p e = " s u b m i t " n g - d i s a b l e d = " ! c o n d i t i o n " > < / b u t t o n >
  37. CORE: NG-SHOW Also an ng-hide, both used depending on conditional

    state < a h r e f = " " n g - c l i c k = " t o g g l e = ! t o g g l e " > T o g g l e n a v < / a > < u l n g - s h o w = " t o g g l e " > < l i > L i n k 1 < / l i > < l i > L i n k 2 < / l i > < l i > L i n k 3 < / l i > < / u l >
  38. EXPRESSIONS Inline JavaScript expression operators

  39. EXPRESSIONS: 'LENGTH' COMPARISONS, 'AND', 'OR' < h 3 > {

    { e m a i l s . m e s s a g e s & & ' E m a i l s ' | | ' N o e m a i l s ' } } < p n g - s h o w = " e m a i l s . m e s s a g e s . l e n g t h > 0 " > { { e m a i l s . m e s s a g e s . l e n g t h } } < / p > < / h 3 > < u l > < l i n g - r e p e a t = " m e s s a g e i n e m a i l s . m e s s a g e s " > < / l i > < / u l >
  40. ROUTING Dynamic views, used with ng-view

  41. ROUTING: DYNAMIC VIEW CONFIG m y A p p .

    c o n f i g ( [ ' $ r o u t e P r o v i d e r ' , f u n c t i o n ( $ r o u t e P r o v i d e r ) { $ r o u t e P r o v i d e r . w h e n ( ' / ' , { t e m p l a t e U r l : ' v i e w s / m a i n . h t m l ' } ) . w h e n ( ' / c a r t / i t e m : i d ' , { t e m p l a t e U r l : ' v i e w s / c a r t - i t e m . h t m l ' } ) . o t h e r w i s e ( { r e d i r e c t T o : ' / ' } ) ; } ] ) ;
  42. SERVER-SIDE RENDER DATA Hooking data sent down on page load

    into Angular
  43. SERVER-SIDE: INSTANT JSON Perf benefits, no $http onload < !

    - - i n s i d e i n d e x . h t m l ( b o t t o m o f p a g e o f c ) - - > < s c r i p t > < / s c r i p t > w i n d o w . g l o b a l D a t a = { } ; g l o b a l D a t a . e m a i l s = < j a v a T a g H e r e T o G e n e r a t e M e s s a g e s > ;
  44. SERVER-SIDE: ANGULAR REFERENCE m y A p p . c

    o n t r o l l e r ( ' E m a i l s C t r l ' , f u n c t i o n ( $ s c o p e ) { $ s c o p e . e m a i l s = { } ; $ s c o p e . e m a i l s . m e s s a g e s = g l o b a l D a t a . e m a i l s ; } ] ) ;
  45. DEPENDENCY INJECTION Tell the app what APIs you want, Angular

    only grabs things it needs Minification
  46. DI: BEFORE MINIFICATION m y A p p . c

    o n t r o l l e r ( ' M a i n C t r l ' , [ ' $ s c o p e ' , ' D e p e n d e n c y ' , ' S e r v i c e ' , ' F a c t o r y ' , / / a r r a y f u n c t i o n ( $ s c o p e , D e p e n d e n c y , S e r v i c e , F a c t o r y ) { / / c o d e } ] ) ;
  47. DI: AFTER MINIFICATION m y A p p . c

    o n t r o l l e r ( ' M a i n C t r l ' , [ ' $ s c o p e ' , ' D e p e n d e n c y ' , ' S e r v i c e ' , ' F a c t o r y ' , / / k e e p s r e f e r e n c e f u n c t i o n ( a , b , c , d ) { / / a = $ s c o p e / / b = D e p e n d e n c y / / c = S e r v i c e / / d = F a c t o r y } ] ) ;
  48. THINKING ANGULAR (NG-THINKING) Scopes and data, not DOM, no add/remove/toggle

    classes, ever. Angular does this all for you based on data Let the data do the work, keep code as minimal as possible Abstract, abstract, abstract. Keep abstracting into different files for better management and copying individual files into new projects, premade working code