backbone.js - Backbone project organization -



backbone.js - Backbone project organization -

i'm struggling bit coming clean, solid way organize backbone application. i'm using requirejs, handlebars, , requirejs text plugin dynamically load html views. simplify things, let's site has next pages:

home: displays collection of products

about: static page

account: contains business relationship information. products purchased, allows various updates. lots of functionality. has tabs navigate different sections.

so i'm going spa loads new pages div ('.backbone-view'). should have general appview el: $('.backbone-view') called when route changes , loads appropriate template? or should have view every page (homeview, aboutview, accountview), el set backbone-view?

beyond that...do need model except products? static page, load in html template , that's it. products, need phone call products collection, renders each product view, each of beingness associated product model. that's fine...but initialize these product constructs? when route home page, do there? have pseudo-code:

routes: { '': 'home', 'about': 'about', 'my-account': 'myaccount', '*default': 'home' }, 'home': function() { // grab template home page // load products // replace $('.backbone-view') home page template populated products }, 'about': function() { // grab template , replace $('.backbone-view') contents }, 'myaccount': function() { mind explosion }

i think big issue i'm not clear on purpose of views...can used page transitions, or should have model attached them? if former, @ to the lowest degree need appview , views each page, right? i'm lost delegate each step...so help appreciated.

thanks help!

here few tips after working on big backbone apps. it's not exhaustive or final..

divide 2 directories

the server directory e.g server/ the publicly accessible directory e.g. www/

also when run build task build app distributable version build/ or dist/ directory. using gulp or grunt.

extend backbone

your entire app consist of:

views & sub views routers & sub routers models collections

you should extend backbone classes if empty @ first. useful 2 extensions are:

sub views (a view can have views object/function more views, cleaned when remove parent view). models , collections called model or collection automatically passed downwards sub views. sub routers (it's nice have routing logic each module within module folder)

use pod architecture

as in organise app around self-contained modules e.g.:

www/app/modules/home/router.js <-- sub router, calls methods in modules.js www/app/modules/home/module.js <-- prepares endpoints - changing layout, initializing views & models etc www/app/modules/home/views/... views (can have subfolders too) www/app/modules/home/templates/ www/app/modules/home/models/ www/app/modules/home/collections

start seeing app in terms of views , sub views

a page doesn't consist of 1 view. have perhaps special "layout" view , within many views - 1 splits page in half, 1 has pagination more views within each page number, view form lots of sub views within each form element , message etc etc

you can start thinking of views shadowing dom tree , split logically - think re-useable on page create bundle (it's own views , models/collections if needs them).

models info , logic performed on data, if view showing server/api/database typically passed view pass or of model attributes template.

if item displaying info in list, collection manage each model each item.

do communication models

if find wanting communicate view view, utilize shared model. view should decoupled possible (it shouldn't need aware of it's parent).

have app state

create model called appstate broadly communicate across app using triggers , listens.

have packages folder (optional)

whenever come across stuff in app think re-useable, in other future apps, create package. these typically hosted on own git repos , pull them projects using package.json or command line.

have folder extend inter-app stuff

have extensions folder modules consumed multiple apps - e.g. backbone extensions go here. or, if created bundle forms want app, extend here.

e.g. www/app/extensions/view.js www/app/extensions/model.js www/app/extensions/collection.js www/app/extensions/buttons/link.js // extending link view "buttons" package.

assets

the reason why have app/ folder in public www/ folder have assets folder in there fonts , images etc:

www/assets/css www/assets/images

note: maybe want seek , maintain assets in module folders (inline pod architecture). haven't done before it's worth considering.

index.html

typically if using commonjs or amd index.html boilerplate no actual dom elements , have 1 phone call in there entry js file. since commonjs has compile <script src="/app.js"></script> amd more like:

<!--if not build--> <script data-main="/app/config" src="/packages/require.js"></script> <!--else <script src="/app.js"></script> -->

so when running in dev (non-build) requirejs load app/config.js in build whole app in app.js. there various grunt/gulp build tasks above (obviously conditional syntax made up).

layouts

i create extensions/layout.js extends extensions/view.js , simple extension have sub views normal (e.g. header , footer), special subview attach view (for body subview) e.g. method setcontentview(view).

i maybe create module called layouts , in there have directory modules/layout/default has view has header , footer subviews. reaching index route flow this:

app/router.js => app/modules/home/router.js => app/modules/home/module.js@index => setcontentview(view app/modules/home/views/index.js)"

routing

i have app router located @ e.g. www/app/router.js have special routes largely subroute object pointed @ sub routers:

subrouters: { 'store-locator': storelocatorrouter, myaccount: myaccountrouter, sitemap: sitemaprouter }

i create possible extending normal backbone router (note in extension need phone call initsubrouters in initialize) -

define([ 'underscore', 'backbone' ], function(_, backbone) { 'use strict'; /** * extended backbone boilerplate router * @class extensions/router * @extends backbone/view */ var router = backbone.router.extend( /** @lends extensions/router.prototype */ { /** * holds reference sub-routers * @type {object} */ subrouters: {}, /** * adds sub-routing * based on https://gist.github.com/1235317 * @param {string} prefix string prefixed route values */ constructor: function(options) { if (!options) { options = {}; } var routes = {}, prefix = options.prefix; if (prefix) { // ensure prefixes have 1 trailing slash prefix.replace(/\/*$/, '/'); } else { // prefix optional, set empty string if not passed prefix = ''; } if (prefix) { // every route needs prefixed _.each(this.routes, function(callback, path) { if (path) { routes[prefix + '/' + path] = callback; } else { // if path "" set prefix, comply // how backbone expects base of operations paths gallery vs gallery/ routes[prefix + '(/)'] = callback; } }); // must override prefixed routes this.routes = routes; } // .navigate needs subrouter prefix this.prefix = prefix; // required have backbone set routes backbone.router.prototype.constructor.apply(this, arguments); }, /** * sets 'beforeroute' event. */ initialize: function() { // round way of adding beforeroute event , must // happen before other routes added. backbone.history.route({ test: this.beforeroute }, function() {}); }, /** * called before routes. * @return {boolean} false ensures 'route' disabled. */ beforeroute: function() { backbone.history.trigger('beforeroute'); homecoming false; }, /** * adds prefix navigation routes * @param {string} route non-prefixed route * @param {object} options passed through backbone.router.navigate */ navigate: function(route, options) { if (route.substr(0, 1) !== '/' && route.indexof(this.prefix.substr(0, this.prefix.length - 1)) !== 0) { route = this.prefix + route; } backbone.router.prototype.navigate.call(this, route, options); }, /** * initializes sub-routers defined in `this.subrouters` */ initsubrouters: function() { _.each(this.subrouters, function(router, name) { this[name] = new router({ prefix: name }); }, this); } }); homecoming router; });

backbone.js requirejs handlebars.js organization

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -