Asynchronous Interfaces

1,050 views

Published on

LRUG talk on using SuperApp with Rails - letting you create beautiful and fast web apps. Also includes a section on Juggernaut 2.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,050
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Lot of JavaScript in this talk! Should really be speaking at LJUG.

  • Google going to add it to pagerank.


  • Group chat app. For developers. iPad.

  • using MacRuby/WebKit
  • What’s great is this interface is realtime - synced between all clients. Even the file upload progress bar are synced - everybody can see when a file is being uploaded.
  • You client should be able to function without a server.
  • Just learn JavaScript - it’s too important for you not too.

  • Don’t like any framework that abstracts away from the DOM. Want something like light, lik JQuery, componentized and flexible.

  • Rather than give you a high level I’m going to be as practical as possible, and go through various libraries I’ve built











  • Facebook search. Needs to be accessed locally so your UI is instantaneous.











  • Pass a function as the last argument to get a callback.
  • We’ve added class support to JavaScript, now we need to add ‘require’ support.





  • If you want to add other variables to the page, such as a user-id, such is the way to do it.
  • So, now that I’ve explained the various libraries and techniques I use, I want to tackle one of the major UI flaws - file uploading. Tangent.
  • HTML5 lets you drag and drop files to upload them
  • But the API requires you to implement at least 5 methods to get it work
  • http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html





  • Webkit lets you upload files by pasting them too.




  • No request/response model

  • Created when I was 16



  • Group chat
  • Single user chat
  • One of the few pieces of Ruby in this talk
    Juggernaut Ruby client


  • Just add a class observer

  • Looking for consultancy
  • Asynchronous Interfaces

    1. 1. Asynchrono us Or, how to build a great web experience.
    2. 2. •Responsive • Non blocking • Realtime
    3. 3. Speed Is essential
    4. 4. Fred Wilson 10 golden rules for building successful web apps
    5. 5. Or Perceived Speed
    6. 6. Holla New name please?
    7. 7. Move logic and rendering
    8. 8. Forget RJS
    9. 9. Options?
    10. 10. SproutCore Cappuccino
    11. 11. Libraries, libraries, everywhere
    12. 12. SuperClass SuperApp SuperModel SuperConnect SuperRPC
    13. 13. SuperClass Very simple class abstraction & inheritance
    14. 14. var SuperApp = new SuperClass; SuperApp.include(SuperEvent); SuperApp.include({ init: function(name){ this.name = name; } }); var App = new SuperApp("name"); App.bind("load", function(){}); SuperApp.extend({ // Class methods })
    15. 15. SuperApp
    16. 16. SuperApp •State Machine • Global Events • Modular
    17. 17. (function($){ var state = App.state.add("loading"); state.afterEnter(function(){ App.log("Loaded state!") }); state.setup(function(){ App.log("Executed on first instantiation") }); state.load(function(){ App.log("Executed on page load") }); })(jQuery); App.state.change("loading")
    18. 18. SuperApp.Vi Simple view manager
    19. 19. App.state.view = new SuperApp.View($("#views"));
    20. 20. <div id="views"> <div class="loading" data-view="loading"> <h2>Loading...</h2> </div> <div class="channel" data-view="channel"> ... </div> </div>
    21. 21. SuperModel ORM
    22. 22. var Channel = SuperModel.setup("Channel"); Channel.attributes = ["name"]; var channel = new Channel; channel.name = "Foo" channel.save();
    23. 23. Preload data Instant access
    24. 24. class RiaController < ApplicationController before_filter :require_user respond_to :html, :json layout false def index end def loader @activity = current_user.activity @channel_activity = current_user.channel_activity @channels = current_user.channels @users = [current_user] render :json => { :activity => @activity, :channel_activity => @channel_activity, :channels => @channels, :users => @users } end end
    25. 25. jQuery(function($){ App.trigger("loading"); var loader = function(data){ for (var name in data) { var model = $.constantize($.classify(name)); model.populate(data[name]); } App.state.change("loaded"); }; $.ajax({ url: "/ria/loader", dataType: "json", cache: false, success: loader }); });
    26. 26. SuperConne Templating & binding
    27. 27. <div> <ul id="channels"> <li>${name}</li> </ul> </div>
    28. 28. var element = $("#channels"); var connector = new SuperConnect(Channel, element);
    29. 29. SuperRPC JSON RPC
    30. 30. class RiaController < ApplicationController before_filter :require_user respond_to :html, :json include SuperRPC::Controller end
    31. 31. class ChannelActivity < SuperModel::Base include SuperRPC::Model end
    32. 32. SuperRPC.invoke( "ChannelActivity", "update", [1, {name: "New name"}] );
    33. 33. user.saveRemote();
    34. 34. Sprockets
    35. 35. app javascripts application.js lib models channel.js user.js states channel.js search.js
    36. 36. gem "rack-sprockets" gem "yui-compressor" config.middleware.use "Rack::Sprockets", :load_path => ["app/javascripts/", "app/javascripts/lib/"]
    37. 37. //= require <jquery> //= require <rails> //= require <rails.application>
    38. 38. What else?
    39. 39. jquery.drop.j
    40. 40. this.view.dropArea(); this.view.bind("drop", this.proxy(function(e){ e.stopPropagation(); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; for ( var i = 0; i < files.length; i++) this.createAsset(files[i]); return false; }));
    41. 41. FileReader
    42. 42. if (typeof FileReader != "undefined" && file.type.match(/image.*/) && file.size < 50000000) { var reader = new FileReader(); reader.onload = function(e) { img.attr({src: e.target.result}); }; reader.readAsDataURL(file); }
    43. 43. File Uploads
    44. 44. jquery.upload.j
    45. 45. $.upload(file, options);
    46. 46. One more thing...
    47. 47. Realtime
    48. 48. Juggernaut
    49. 49. 4 Years Old
    50. 50. Juggernaut 2
    51. 51. What’s new? • WebSocket support • Built on Node.js • Horizontally scalable • PubSub model • Even more simple!
    52. 52. <script src="http://localhost:8080/application.js" type="text/ javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> jQuery(function($){ var jug = new Juggernaut; jug.subscribe("/chats", function(data){ // ETC }); }); </script>
    53. 53. <script src="http://localhost:8080/application.js" type="text/ javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> jQuery(function($){ var jug = new Juggernaut; jug.subscribe("/chats", function(data){ $("#chats").append($("<li />").text(data)); }); }); </script>
    54. 54. <script src="http://localhost:8080/application.js" type="text/ javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> jQuery(function($){ var jug = new Juggernaut; jug.subscribe("/chats/203942lkj34u0uasdf084", function(data){ $("#chats").append($("<li />").text(data)); }); }); </script>
    55. 55. Juggernaut.publish("/chats","Hello World!")
    56. 56. http://github.com/
    57. 57. @maccman

    ×