Successfully reported this slideshow.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

A Better UJS for Rails

  1. 1. A Better UJS for Rails Codemy.net presents @zacksiriby: Monday, June 10, 13
  2. 2. Javascript is a big part of Rails Project Monday, June 10, 13
  3. 3. No real convention for working with JS files Monday, June 10, 13
  4. 4. Backbone is Great but... Monday, June 10, 13
  5. 5. I miss working with Ruby Monday, June 10, 13
  6. 6. And then I saw Turbolinks... Monday, June 10, 13
  7. 7. Monday, June 10, 13
  8. 8. Turbolinks Backbone / MV* Control / Complexity for Client Less Ruby Monday, June 10, 13
  9. 9. So I thought long and hard Monday, June 10, 13
  10. 10. Turbolinks Backbone / MV* ? Something is missing Control / Complexity for Client Less Ruby Monday, June 10, 13
  11. 11. Transponder JS http://www.github.com/zacksiri/transponder Extracted from Codemy Monday, June 10, 13
  12. 12. 3 Core Components • Helpers • Presenters • Services Monday, June 10, 13
  13. 13. CH.calendar = Codemy.Helpers.Calendar =   dateOnly: (date_time) ->     moment(date_time).format('YYYY-MM-DD')     timeInISO: (date_time) ->     moment(date_time).format('YYYY-MM-DD HH:mm:ss Z')     timeInHour: (date_time) ->     moment(date_time).format('HH:mm A') Monday, June 10, 13
  14. 14. class CommentsPresenter extends Transponder.Presenter   presenterName: 'comments'   modelName: 'comment'     index: ->     if @params.page       CH.infiniteLoader.loadNext         element: @element         response: @response         modelName: @modelName         putAt: 'prepend'     show: ->     $(@element).replaceWith(@response)     $(@element).trigger('codemy:services:highlight')   ....     create: ->     $('#new_comment').replaceWith(@response)     $(".comment:last").effect('highlight', {}, 500)     destroy: ->     $(@element).fadeOut 300, ->       $(this).remove() Monday, June 10, 13
  15. 15. • maps to your controller actions • calls helper functions when needed • trigger services • modify the DOM as needed Presenters Monday, June 10, 13
  16. 16. How does it work? Monday, June 10, 13
  17. 17. class CommentsPresenter extends Transponder.Presenter   presenterName: 'comments'   modelName: 'comment'     index: ->     # your code for modifying the DOM     # listens for event ujs:comments:index     update: ->     # listens for even ujs:comments:update ... • ujs:comments:index triggers index() • ujs:comments:show triggers show() • ujs:comments:edit triggers edit() • ujs:comments:update triggers update() • ujs:comments:create triggers create() • ujs:comments:destroy triggers destroy() Monday, June 10, 13
  18. 18. Ok so how do I trigger the event? Monday, June 10, 13
  19. 19. $('#comments').trigger("<%= j ujs_event_type %>", "<%= j render 'comments' %>"); app/views/comments/index.js.erb app/views/comments/update.js.erb $('#comment_1').trigger("<%= j ujs_event_type %>", "<%= j render @comment %>"); { ujs:comments:update { controller_name:action_name Monday, June 10, 13
  20. 20. class CommentsPresenter extends Transponder.Presenter   presenterName: 'comments'   modelName: 'comment'     index: ->     if @params.page       CH.infiniteLoader.loadNext         element: @element         response: @response         modelName: @modelName         putAt: 'prepend'     update: ->     $(@element).replaceWith(@response)     ... Monday, June 10, 13
  21. 21. Presenters Provide • Better code reusability (Dryer) • Cleaner • Provides Structure • Use what you already know! • Logicless View in Rails Monday, June 10, 13
  22. 22. What are services? Monday, June 10, 13
  23. 23. Monday, June 10, 13
  24. 24. <select>   <option value="drafting">drafting</option>   <option value="request_approval"> awaiting approval </option> </select> Monday, June 10, 13
  25. 25. class Codemy.Services.SubmitOnChange extends Transponder.Service   serviceName: 'codemy:services:submit_on_change'     serve: ->     @element.on 'change', (e) ->       e.preventDefault()       form = $(this).parents('form')       $.ajax         url: form.attr('action')         type: 'PUT'         dataType: 'script'         data: $(form).serialize() Monday, June 10, 13
  26. 26. <select class="submit_on_change">   <option value="drafting">drafting</option>   <option value="request_approval"> awaiting approval </option> </select> $('body.courses.index').trigger('codemy:services:submit_on_change'); <select class="submit_on_change submit_on_change_active">   <option value="drafting">drafting</option>   <option value="request_approval"> awaiting approval </option> </select> Monday, June 10, 13
  27. 27. Transponder.service_manifest = ->   $("body.questions,      body.apprentice.objectives.show,      body.mentor.owned_levels.show,      body.mentor.objectives.show,      body.mentor.posts,      body.posts.show").trigger       'codemy:services:live_preview'     $("body.questions,      body.mentor.posts").trigger     'codemy:services:tag_select'     $("body.questions,      body.apprentice,      body.mentor,      body.activities,      body.posts.show").trigger       'codemy:services:highlight' Monday, June 10, 13
  28. 28. What Services Do • Write once use everywhere (again Dryer code) • Better Maintainability • Makes sure it doesn’t run on a node that has that service already running • Makes it easier to manage all your code via manifest Monday, June 10, 13
  29. 29. How do they all Work Together? Monday, June 10, 13
  30. 30. class BadgesPresenter extends Transponder.Presenter   nameSpace: "mentor"   presenterName: "badges"   modelName: "badge"     show: ->     $(@element).replaceWith(@response)     $(@element).trigger('codemy:services:poller')     $(@element).trigger('codemy:services:uploader')     update: ->     @show() Monday, June 10, 13
  31. 31. Monday, June 10, 13
  32. 32. $(document).ready triggers uploader service User uploads uploader service runs Runs Update action in Presenter Triggers poller service renders processed image to browser through presenter 1 2 3 4 5 6 Monday, June 10, 13
  33. 33. Transponder works with Everything Monday, June 10, 13
  34. 34. Not Saying don’t use Backbone Monday, June 10, 13
  35. 35. Use the right tools for the job. Monday, June 10, 13
  36. 36. Codemy uses Turbolinks with Transponder and Backbone when appropriate Monday, June 10, 13
  37. 37. Transponder is out! http://www.github.com/zacksiri/transponder Monday, June 10, 13
  38. 38. # TODO: • Clean up some APIs • Add Documentation • Video Screencasts • More Generators • Example Rails Project Monday, June 10, 13
  39. 39. Thank You! @codemy_net Questions? @zacksiri Monday, June 10, 13

×