By Muetton Julien / @themouette
APIHour @clermontech 2013 july, 3rd
A component's responsability is to provide meaningful user experience.
But it requires a lot of boilerplate.
The application main entry point
Load dependencies Get remote data Register routes Setup UI Show loading Wait for data Start routerResponsible for boot sequence and modules orchestration
var myApp = new Fossil.Application({ routes: { '': function () { this.routing.navigate('search', {replace: false}); }, fragments: { 'topmenu': TopmenuFragment } }); myApp // declare services .use('routing', Fossil.Services.Routing) .use('session', Fossil.Services.Session); myApp // connect modules .connect('search', SearchModule) .connect('configure/:model', ConfigureModule) myApp.start();
Consistent package of UI, business and data.
var SearchModule = Fossil.Module.extend({ routing: { ':query': 'onquery' }, fragments: { 'sidebar': SidebarFragment, 'content': ContentFragment }, onqueryRoute: function (query) { this .abort() // abort previous calls .waitFor(this.ensureCollection().fetch({query: query})) .thenWith(this, this.renderResults, this.displayError); }, renderResults: function () { this.trigger('search:query:render'); } });
Standalone set of views, with its own logic.
Can be included in Application, Modules and Fragments.
Never manage UI in Modules or Application, send events to Fragments.
var SidebarFragment = Fossil.Fragment.extend({ ancestorEvents: { 'search:query:render': function (results) { this.setView(new Fossil.View.Collection({ ItemView: ResultRowView, collection: results })); } } });
var myApp = new Fossil.Application({ routes: { '': function () { this.routing.navigate('search', {replace: false}); }, fragments: { 'topmenu': TopmenuFragment } }); myApp // declare services .use('routing', Fossil.Services.Routing) myApp // connect modules .connect('search', SearchModule) .connect('configure/:model', ConfigureModule) myApp.start();
No unit tests needed, it is just configuration
var SearchModule = Fossil.Module.extend({ routing: { ':query': 'onquery' }, onqueryRoute: function (query) { this .abort() // abort previous calls .waitFor(this.ensureCollection().fetch({query: query})) .thenWith(this, this.renderResults, this.displayError); }, renderResults: function () { this.trigger('search:query:render'); } });
var SidebarFragment = Fossil.Fragment.extend({ ancestorEvents: { 'search:query:render': function (results) { this.setView(new Fossil.View.Collection({ ItemView: ResultRowView, collection: results })); } } });