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

RailsConf 2015: Your Front-end Framework is Ove...

RailsConf 2015: Your Front-end Framework is Overkill - Server Side Javascript Responses w/ Rails

For dynamic apps, Rails has taken a backseat to client side frameworks such as AngularJS, Ember and Backbone.

Learn how to use server side javascript effectively to greatly simplify your code base and reuse your view logic. We'll implement parallel apps with vanilla Rails js responses, AngularJS and Ember.js so that we can contrast the implementations and evaluate the tradeoffs.

Avatar for Jim Jones

Jim Jones

April 23, 2015
Tweet

More Decks by Jim Jones

Other Decks in Programming

Transcript

  1. WHO AM I? JIM JONES software engineer, karaoke enthusiast, husband,

    dad Rails consultant, currently at One Kings Lane @aantix [email protected] http://www.aantix.com/ http://www.github.com/aantix
  2. OLD SCHOOL RJS < % = l i n k

    _ t o _ r e m o t e ( " T e s t o u t R J S ! " , : u r l = > { : c o n t r o l l e r = > " r j s " , : a c t i o n = > " h e l l o " } ) % >
  3. RUBY MAKES A HORRIBLE.. JAVASCRIPT # v i e w

    s / t a s k / c r e a t e . r j s p a g e . r e p l a c e _ h t m l ( ' t a s k s - c o m p l e t e d ' , T a s k . c o m p l e t e d _ c o u n t ) p a g e . r e p l a c e _ h t m l ( ' t a s k s - r e m a i n i n g ' , T a s k . r e m a i n i n g _ c o u n t ) p a g e . r e p l a c e _ h t m l ( ' t a s k - s t a t u s - ' + @ t a s k . i d . t o _ s , @ t a s k . s t a t u s . d e s c r i p t i o n )
  4. RAILS SERVER SIDE JAVASCRIPT RESPONSES Rails serves up Javascript that

    is eval'ed by jQuery client side. The template is first preprocessed by the template handler (erb, haml) Template is still processed by template engine Allows for reuse of any partial jQuery by default evals any JS response
  5. Double-click to edit a todo Created by Matt De Leon

    Part of TodoMVC todos 2 items left All Active Completed What needs to be done? » Get Milk ✔ Do slides for talk ✔
  6. VIEW (FORM) < h e a d e r i

    d = " h e a d e r " > < h 1 > t o d o s < / h 1 > < % = f o r m _ f o r ( T o d o . n e w , r e m o t e : t r u e ) d o | f | % > < % = f . t e x t _ f i e l d : t i t l e , p l a c e h o l d e r : " W h a t n e e d s t o b e d o n e ? " , i d : " n e w - t o d o " , a u t o f o c u s : t r u e , " d a t a - b e h a v i o r " = > " s u b m i t _ o n _ e n t e r " % > < % e n d % > < / h e a d e r >
  7. MODEL c l a s s T o d o

    < A c t i v e R e c o r d : : B a s e s c o p e : c o m p l e t e d , - > { w h e r e ( " c o m p l e t e d = ? " , t r u e ) } s c o p e : a c t i v e , - > { w h e r e ( " c o m p l e t e d = ? " , f a l s e ) } . . . . e n d
  8. VIEW # a p p / v i e w

    s / t o d o s / c r e a t e . j s . e r b $ ( " # t o d o - l i s t " ) . a p p e n d ( " < % = j ( r e n d e r ( @ t o d o ) ) % > " ) ; $ ( " # n e w - t o d o " ) . v a l ( " " ) ;
  9. CONTROLLER c l a s s T o d o

    s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r . . . d e f c r e a t e @ t o d o = T o d o . n e w ( t o d o _ p a r a m s ) @ t o d o . s a v e e n d . . . . e n d p r i v a t e d e f t o d o _ p a r a m s p a r a m s . r e q u i r e ( : t o d o ) . p e r m i t ( : t i t l e , : c o m p l e t e d ) e n d
  10. FORM IS SUBMITTED < f o r m a c

    t i o n = " / t o d o s " c l a s s = " n e w _ t o d o " d a t a - r e m o t e = " t r u e " i d = " n e w _ t o d o " . . . < / f o r m >
  11. JQUERY-UJS AND DATA-REMOTE / / j q u e r

    y - u j s / s r c / r a i l s . j s $ d o c u m e n t . d e l e g a t e ( r a i l s . f o r m S u b m i t S e l e c t o r , ' s u b m i t . r a i l s ' , f u n c t i o n ( e ) / / . . . . . i f ( r e m o t e ) { / / . . r a i l s . h a n d l e R e m o t e ( f o r m ) ; r e t u r n f a l s e ; } } / / . . . . . . . . . . . . . . . . . h a n d l e R e m o t e : f u n c t i o n ( e l e m e n t ) { v a r m e t h o d , u r l , d a t a , e l C r o s s D o m a i n , c r o s s D o m a i n , w i t h C r e d e n t i a l s , d a t a T y p e ,
  12. CONTROLLER ACTION IS CALLED S t a r t e

    d P O S T " / t o d o s " f o r 1 2 7 . 0 . 0 . 1 a t 2 0 1 5 - 0 4 - 1 3 1 9 : 0 6 : 0 7 - 0 5 0 0 P r o c e s s i n g b y T o d o s C o n t r o l l e r # c r e a t e a s J S P a r a m e t e r s : { " u t f 8 " = > " ✓" , " t o d o " = > { " t i t l e " = > " G e t M i l k " } } ( 0 . 1 m s ) b e g i n t r a n s a c t i o n S Q L ( 2 . 4 m s ) I N S E R T I N T O " t o d o s " ( " c r e a t e d _ a t " , " t i t l e " , " u p d a t e d _ a t " . . .
  13. CREATE.JS RESPONSE RENDERED AND ESCAPED ERB # _ t o

    d o . j s . e r b r e n d e r e d $ ( " # t o d o - l i s t " ) . a p p e n d ( " < % = j ( r e n d e r ( @ t o d o ) ) % > " ) ; HAML = = $ ( " # t o d o - l i s t " ) . a p p e n d ( " # { e s c a p e _ j a v a s c r i p t ( r e n d e r ( @ t o d o ) ) } " ) ;
  14. JQUERY EVAL OF JS REQUESTS / / s r c

    / a j a x / s c r i p t . j s j Q u e r y . a j a x S e t u p ( { / / . . . . . c o n t e n t s : { s c r i p t : / ( ? : j a v a | e c m a ) s c r i p t / } , c o n v e r t e r s : { " t e x t s c r i p t " : f u n c t i o n ( t e x t ) { j Q u e r y . g l o b a l E v a l ( t e x t ) ; r e t u r n t e x t ; } } } ) ;
  15. Official Resources Tutorial API Reference Developer Guide Applications built with

    AngularJS Blog FAQ Videos Articles and Guides Code School AngularJS course 5 Awesome AngularJS Features Using Yeoman with AngularJS me&ngular - an introduction to MVW Community Walkthroughs and Tutorials on YouTube Google Groups mailing list angularjs on Stack Overflow AngularJS on Twitter AngularjS on Google+ If you have other helpful links to share, or find any of the links above no longer work, please let us know. ” AngularJS
  16. VIEW < b o d y n g - a

    p p = " t o d o m v c " > < n g - v i e w / > < s c r i p t t y p e = " t e x t / n g - t e m p l a t e " i d = " t o d o m v c - i n d e x . h t m l " > < s e c t i o n i d = " t o d o a p p " > < h e a d e r i d = " h e a d e r " > < h 1 > t o d o s < / h 1 > < f o r m i d = " t o d o - f o r m " n g - s u b m i t = " a d d T o d o ( ) " > < i n p u t i d = " n e w - t o d o " p l a c e h o l d e r = " W h a t n e e d s t o b e d o n e ? " < / f o r m > < / h e a d e r > < s e c t i o n i d = " m a i n " n g - s h o w = " t o d o s . l e n g t h " n g - c l o a k > < i n p u t i d = " t o g g l e - a l l " t y p e = " c h e c k b o x " n g - m o d e l = " a l l C h e c k e d " < l a b e l f o r = " t o g g l e - a l l " > M a r k a l l a s c o m p l e t e < / l a b e l > < u l i d = " t o d o - l i s t " > < l i n g - r e p e a t = " t o d o i n t o d o s | f i l t e r : s t a t u s F i l t e r t r a c k b y $ i n d e
  17. CONTROLLER a n g u l a r . m

    o d u l e ( ' t o d o m v c ' ) . c o n t r o l l e r ( ' T o d o C t r l ' , f u n c t i o n T o d o C t r l ( $ s c o p e , $ r o u t e P a r a m s , $ f i l t e r , s t o r e ) { ' u s e s t r i c t ' ; v a r t o d o s = $ s c o p e . t o d o s = s t o r e . t o d o s ; $ s c o p e . n e w T o d o = ' ' ; $ s c o p e . e d i t e d T o d o = n u l l ; / / / / / $ s c o p e . a d d T o d o = f u n c t i o n ( ) { v a r n e w T o d o = { t i t l e : $ s c o p e . n e w T o d o . t r i m ( ) , c o m p l e t e d : f a l s e } ;
  18. SERVICES a n g u l a r . m

    o d u l e ( ' t o d o m v c ' ) . f a c t o r y ( ' t o d o S t o r a g e ' , f u n c t i o n ( $ h t t p , $ i n j e c t o r ) { ' u s e s t r i c t ' ; / / . . . . . i n s e r t : f u n c t i o n ( t o d o ) { v a r o r i g i n a l T o d o s = s t o r e . t o d o s . s l i c e ( 0 ) ; r e t u r n $ h t t p . p o s t ( ' / a p i / t o d o s ' , t o d o ) . t h e n ( f u n c t i o n s u c c e s s ( r e s p ) { t o d o . i d = r e s p . d a t a . i d ; s t o r e . t o d o s . p u s h ( t o d o ) ; r e t u r n s t o r e . t o d o s ; } , f u n c t i o n e r r o r ( ) { a n g u l a r . c o p y ( o r i g i n a l T o d o s , s t o r e . t o d r e t u r n s t o r e . t o d o s ; }
  19. Double-click to edit a todo Created by Tom Dale, Addy

    Osmani Updated by Cory Forsyth Part of TodoMVC Example Demo, Source Official Resources Guides API Reference Screencast - Building an App with Ember.js Applications built with Ember.js Blog Articles and Guides Getting Into Ember.js EmberWatch Community Ember.js on Stack Overflow Ember.js on Twitter Ember.js on Google+ If you have other helpful links to share, or find any of the links above no longer work, please let us know. A framework for creating ambitious web applications. “ ” Ember.js 1 item left What needs to be done? All Active Completed ❯ Sleep
  20. VIEW < s c r i p t t y

    p e = " t e x t / x - h a n d l e b a r s " d a t a - t e m p l a t e - n a m e = " t o d o s " > < s e c t i o n i d = " t o d o a p p " > < h e a d e r i d = " h e a d e r " > < h 1 > t o d o s < / h 1 > { { t o d o - i n p u t i d = " n e w - t o d o " t y p e = " t e x t " v a l u e = n e w T i t l e < / h e a d e r > { { o u t l e t } } / / . . . . .
  21. CONTROLLER T o d o s . T o d

    o s C o n t r o l l e r = E m b e r . A r r a y C o n t r o l l e r . e x t e n d ( { a c t i o n s : { c r e a t e T o d o : f u n c t i o n ( ) { v a r t i t l e , t o d o ; / / G e t t h e t o d o t i t l e s e t b y t h e " N e w T o d o " t e x t f i e l t i t l e = t h i s . g e t ( ' n e w T i t l e ' ) . t r i m ( ) ; i f ( ! t i t l e ) { r e t u r n ; } / / C r e a t e t h e n e w T o d o m o d e l t o d o = t h i s . s t o r e . c r e a t e R e c o r d ( ' t o d o ' , { t i t l e : t i t l e , i s C o m p l e t e d : f a l s e } ) ;
  22. MODELS T o d o s . T o d

    o = D S . M o d e l . e x t e n d ( { t i t l e : D S . a t t r ( ' s t r i n g ' ) , i s C o m p l e t e d : D S . a t t r ( ' b o o l e a n ' ) } ) ;
  23. GRACEFUL ERROR RETRIES A p p . S o m

    e R o u t e = E m b e r . R o u t e . e x t e n d ( { a c t i o n s : { / / t h e n t h i s h o o k w i l l b e f i r e d w i t h t h e e r r o r a n d m o s t i m p o r t a n t l y a T r a n / / o b j e c t w h i c h y o u c a n u s e t o r e t r y t h e t r a n s i t i o n a f t e r y o u h a n d l e d t h e e r r o r : f u n c t i o n ( e r r o r , t r a n s i t i o n ) { / / h a n d l e t h e e r r o r c o n s o l e . l o g ( e r r o r . m e s s a g e ) ; / / r e t r y t h e t r a n s i t i o n t r a n s i t i o n . r e t r y ( ) ; } } ) ;
  24. JQUERY UJS CALLBACKS event name extra parameters * when a

    j a x : b e f o r e before the whole ajax business , aborts if stopped
  25. ENABLING THE AJAX ERROR CALLBACK $ ( d o c

    u m e n t ) . o n ( " a j a x : e r r o r " , f u n c t i o n ( x h r , s t a t u s , e r r o r ) { c o n s o l e . l o g ( s t a t u s . r e s p o n s e T e x t ) ; r e t u r n c o n s o l e . l o g ( e r r o r ) ; } ) ;
  26. LOSS OF EVENT BINDINGS / / u p d a

    t e . j s . e r b $ ( " # c a r t - s u m m a r y " ) . r e p l a c e W i t h ( " < % = j ( r e n d e r ( p a r t i a l : " c a r t _ s u m m a r y " ) ) % > " $ ( " # c a r t - s u m m a r y " ) . t r i g g e r ( " u p d a t e d " ) ;
  27. REUSE OF PARTIALS / / c r e a t

    e . j s . e r b / / _ u s e r . h t m l . e r b $ ( " # u s e r s " ) . a p p e n d ( " < % = j ( r e n d e r @ u s e r ) % > " ) ; / / u p d a t e . j s . e r b / / _ u s e r . h t m l . e r b $ ( " # u s e r _ " + < % = @ u s e r . i d % > ) . r e p l a c e W i t h ( " < % = j ( r e n d e r @ u s e r ) % > " ) ;
  28. PERFORMANCE: CACHING OF VIEWS / / c r e a

    t e . j s . e r b / / _ u s e r . h t m l . e r b $ ( " # u s e r s " ) . a p p e n d ( " < % = j ( c a c h e @ u s e r { r e n d e r @ u s e r } ) % > " ) ;
  29. ".. consider how you would solve your immediate problem without

    adding anything new." http://mcfunley.com/choose-boring-technology ..." -- Dan McKinley ( 6.5 years as a Principal Engineer at Etsy)