On Github nathanstitt / devcomo-single-page-apps
nathan@argosity.com
http://github.com/nathanstitt
That are discoverable by the big G
And Bing, DuckDuckGo, etc....
You visit the page, download a bunch of javascript, and all further requests (if any) are made via unobtrusive AJAX.
Can turn into big ball of mud
Who's seen this? (or worse, written it?)
jQuery.extend(Application.Model.prototype, { process: function() { var myVar1; // processing using myVar1; jQuery.ajax({ url:myurl1, dataType:'json', success:function(data) { var myVar2; // process data using myVar1, set state of myVar2, // then send it back jQuery.ajax({ url:myurl2, dataType:'json', success:function(data) { // do stuff with myVar1 and myVar2 if(!data.ok) { jQuery.ajax({ url:myurl2, dataType:'json', success:mycallback }); } else { mycallback(data); } } }); } }); } });
Can be extremely fragile
JS={ foo: function(){ return this.bar(); }, bar: function(){ return "I'm Awesome!"; }, }
who spots it?
Most single page apps do not need to be indexable.
ask if anyone knows of any exceptions. Mention Amazon's hybrid model. 1 second, 7% converstion.Search engines do not execute Javascript
If you sell widgets, it'd be nice if people could find you when they search for 'awesome widgets for sale'
Google kind of does, but only to spot SEO tricks.Is far from a solved problem
Discourse took this approach
Meteor is using this approach
Rails 4 includes Turbolinks to accomplish this.
Portions of the page are swapped dyncically for HTML which is fetched from server
Everything can use standard ERB (or whatever) templates
This is what I settled on and extracted into the LiquidAssets Gem
render :template=>'category/menu', :locals=> { 'cart' => @cart.as_json, 'categories' => @menus.as_json }
To ensure compatability between JS and Ruby, only simple Hash and Array's are supported. Hashes must use string keys (not symbols).
class LB.View.Category.Menu extends Backbone.View render: -> this.$el.html( LB.Render( "category/menu", { categories: this.collection.toJSON(), cart: LB.Data.Cart } ) ) this.attach() return this attach:-> _.each( this.$('li'), (el)-> model = this.collection.get( $(el).attr('data-id') ) view = new LB.View.Category.MenuChoice({ model: model, el: el }) ,this ) this.onMenuSelection() return this
@coffeescript
nathan@argosity.com
github.com/nathanstitt/liquid_assets