I'm wondering how to structure my application. Should I use custom views and one main view that will control them. Or is it better to hold my views in a lightbox. All of the examples I've found are somehow limited of functionality and present a single or a few screens. What is the right way to organize a bigger application?
-
A question must be more specific. this type of question should be discussed on related forums. – Meysam Tolouee May 28 '14 at 11:38
-
I can't imagine more specific question than that. You can contribute with personal practices, examples, links and etc. – user732456 May 28 '14 at 12:23
-
Are you asking us to send you our big projects for you? – Meysam Tolouee May 28 '14 at 12:26
-
No I'm asking to explain how you build it – user732456 May 28 '14 at 12:27
-
There is no correct answer, there are many ways to go about it, and depends on what other tech you are using. – Keith Nicholas May 29 '14 at 21:59
2 Answers
I'm wondering too.
Starting point:
- Famo.us apps are structured in a hierarchical rendering tree.
- Famo.us uses RequireJS modules.
- Famo.us encourages the use of Views
- Views are reusable components.
- Views encapsulate functionality (and part of the rendering tree).
- Views communicate using events.
- View get initialized by an options object.
We need to add structure to manage:
- Business logic
- Non-UI functionality like REST api calls, audio, local storage, etc.
- Data-flow:
- Update data on user input
- Update view on data change
Modules, events and loose coupling
Goals:
- Scalable application structure.
- Small, independent, testable modules.
- Promote re-use of code.
- Easy sharing of modules (just drop a file your project)
- No dependence on other Javascript frameworks.
All to often, there is tight coupling between modules:
- Module instantiates and keeps a reference to another module
- Modules cross their semantic boundries
- A view that knows about a specific REST api
- A view that uses specific model code such as Backbone (see Taasky example)
Here is to how to avoid this:
- Modules emit events when something interesting happens (user input, data change, etc)
- A Mediator listens to the event
- The Mediator calls the public API of another module.
So, instead of having a View-module know about Backbone model stuff, it emits an user input event like this:
- Todo-Edit-View emits "User input" event:
"todo-update",{id:1,title:'Code'}
- Todo-Mediator listens to the event.
- Todo-Mediator calls
tasks.find({id:1}).update({title:'Code'})
of Todo module (e.g. using Backbone)
Rules
- There are Modules and Mediators
- Modules have a public API and emit events
- The API and events stay in their semantic boundries; i.e. "updateTitle()" instead of "onBackboneModelChange()"
- The Mediator couples the app, i.e. a backbone model change to a todo-item title update.
- Mediators are singletons
- An application can have multiple mediators.
For example, an e-mail application like GMail could have mediators for
- chat function
- todo list function
- reading e-mail
- writing & sending e-mail
File structure:
/src
/lib
/services
/mediators
/layout
/content
/config
/main.js
Types of modules:
- Service: An independent module to encapsulate non-UI functions such as: LocalStorage, Ajax, Web Audio, etc.
- Layout: Layout, animation and positioning of content, e.g: ScrollView, HeaderFooterView, etc
- Content: Actual content of the app: leaf nodes (surfaces) of the rendering tree.
Note the distinction between Layout and Content. By seperating UI-components & layout from actual content, it becomes easy to reuse UI patterns such as side-panels, popups, navigation-bars, sticky-headers, scroll-views, etc.
Also, I would recommend creating a *.css
for every Layout containing only structure and minimal theming. All theming can be overriden/extended in config/theme.css
, so it's easy to reskin an app.
Other code:
- Mediator: Couples modules using events and public APIs.
- Config: Contains all options used throughout the app on initialization.
- main.js: Bootstraps the app.
Bootstrap app in Main.js
- Create mediators
- Create services
- Construct rendering tree
Module life-cycle
- A module must be contained in a single file, i.e. don't depend on external libraries!
When a module is created, it announces its presence to all mediators. We use the Famo.us Engine
to emit a global event. This will be the only required dependency!
Engine.trigger('created',this)
When a module is destroyed, it announces its destruction to all mediators.
Engine.trigger('destroyed',this)
The mediator listens to created
and destroyed
events and glues modules together:
var someDataModule; // Backbone or whatever
Engine.on('create',function(module){
if(module instance of SomeDataModule) {
var someDataModule = module;
}
if(module instanceof TodoView) {
module.on('change-title',function({id:id,title:title}){
someDataModule.find({id:id}).set('title',title);
})
}
})
In simple mediators, you can initialiaze modules in order (i.e SomeDataModule
before TodoView
). However, in more complex scenarious, you might need to use a Promise
to couple everything.
Note on dependencies
There are three exceptions on "self-contained" modules:
Layout and Content modules are allowed to have hierachical dependencies. Parents can initialize children, and expect certain events from these children. A
ListView
might initializeItemView
and handleItemRemoved
events.Services can be a Facade/Adapter for another service. For example, a
DataService
might provide an simplification, abstraction and security layer for aRestApiService
.Of course, mediators have hard-wired dependencies because they couple the app!

- 5,569
- 2
- 28
- 34
Famo.us is focused on UI, so you better look for a MVC pattern to have better structure, specially on large projects, actually as Famo.us is very young it only have an integration with Angular:
http://famo.us/integrations/angular/
But is well known that they will add other MVC integrations in the near future
Try Angular and look if it is what you need, it´s a pretty nice MVC Framework, my recommendation is to first learn Angular at least basics (http://angularjs.org/ and then after Famo.us University (http://famo.us/university) you can understand this integration

- 973
- 9
- 16
-
There is also an unofficial Meteor integration: http://famous-components.meteor.com/ (Authored by me, supported by the community) – gadicc Jun 06 '14 at 14:06