Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EmberJS: Good separation of concerns for Models, Stores, Controllers, Views in a rather complex application?

I'm doing a fairly complex emberjs application, and tying it to a backend of APIs.

The API calls are not usually tied to any particular model, but may return objects of various types in different sections of the response, e.g. a call to Events API would return events, but also return media assets and individuals involved in those events.

I've just started with the project, and I'd like to get some expert guidance on how best to separate concerns to have a clean maintainable code base.

The way I am approaching this is:

  • Models: essentially handle records with their fields, and other computed properties. However, models are not responsible for making requests.
    • e.g. Individual, Event, Picture, Post etc.
  • Stores: They are essentially caches. For example, an eventStore would store all events received from the server so far (from possibly different requests) in an array, and also in an hash of events indexed by id.
    • e.g. individualStore, eventStore etc.
  • Controllers: They tie to a set of related API calls, e.g. eventsController would be responsible for fetching events or a particular event, or creating a new event etc. They would 'route' the response to different stores for later retrieval. They don't keep the response once it has been sent to stores.
    • e.g. eventsController, userSearchController etc.
  • Views: They are tied to a particular view. In general, my application may have several views at different places, e.g. latestEventsView on the Dashboard in addition to having a separate events page.
  • Templates: are what they are.

Quite often, my templates require to be bound directly to the stores (e.g. peopleView wants to list all the individuals in the individualStore in a list, sorted by some order).

And sometimes, they bind to a computed property

alivePeople: function () { ... }.property('App.individualStore.content.@each'),

The various filtering and sorting options 'chosen' in the view, should return different lists from the store. You can see my last question at what is the right emberjs way to switch between various filtering options?

Who should do this filtering, the view themselves or the stores?

Is this kind of binding across layers okay, or a code smell? Is the separation of concerns good, or am I missing something? Shouldn't controllers be doing something more here? Should my views directly bind to stores?

Any particular special case of MVC more suited to my needs?

Update 17 April 2012 My research goes on, particularly from http://vimeo.com/user7276077/videos and http://jzajpt.github.com/2012/01/17/emberjs-app-architecture.html and http://jzajpt.github.com/2012/01/24/emberjs-app-architecture-data.html

Some issues with my design that I've figured out are:

  • controllers making requests (stores or models or something else should do it, not controllers)
  • statecharts are missing -- they are important for view-controller interactions (after sometime you realize your interactions are no more simple)

This is a good example of state charts in action: https://github.com/DominikGuzei/ember-routing-statechart-example

UPDATE 9th JANUARY 2013

Yes, it's been long but this question is lately getting lots of views, and that's why I'd like to edit it so that people may get a sense.

Ember's landscape has changed a lot since this question was framed, and the new guides are much improved. EmberJS has come up with conventions (like Rails) and the MVC is much more well defined now.

Anybody still confused should read all the guides, and watch some videos: Seattle Ember.js Meetup

At the moment, I'm upgrading my application to Ember.js 1.0.0-pre2.

like image 267
Kazim Zaidi Avatar asked Apr 12 '12 06:04

Kazim Zaidi


2 Answers

  • You should think of your application in terms of states. Have a look at this

  • Initially, only a route and a template are required to describe something and finally display it in the browser, that's what the new API of Emberjs tries to enforce. As your requirements get more elaborate you can throw in a view, a controller or an object. Each though answers a specific need.

  • Consider a view if you need to handle any browser events or wrap
    any 3rd party javascript lib you're using for animation, styling ..

  • Consider an Object if you need to capture domain specific
    information, most likely mimics backend information.

  • A controller is merely a proxy for the domain object and may encapsulate logic that doesn't pertain necessarily to the object.

That's all what's to it. If you learn how to design your application in terms of states, the rest will fall into the right place, providing you're using the latest api, enforcing the rules i mentioned previously.

like image 137
ken Avatar answered Oct 29 '22 16:10

ken


Since the release of Ember 1.0.0-pre4 with the new router implementation I've seen two good references describing a standardised EmberJS app structure.

Those of you familiar with Rails would find it fairly familiar.

https://github.com/trek/ember-todos-with-build-tools-tests-and-other-modern-conveniences

http://reefpoints.dockyard.com/ember/2013/01/07/building-an-ember-app-with-rails-api-part-1.html

The ember-rails project at https://github.com/emberjs/ember-rails includes a Rails generator for creating an EmberJS application directory structure that is essentially the same as the structure described in the two links above.

The EmberJS guides also now describe the new routing structure. http://emberjs.com/guides/

UPDATE 21/08/2013

If you are using Rails then the ember-rails gem is great. I've used it with a lot of success. There are two efforts within the ember community to assist in providing a standardised ember application layout. Apparently they are going to be merged but for now check out:

https://github.com/rpflorence/ember-tools

https://github.com/stefanpenner/ember-app-kit

like image 45
ianpetzer Avatar answered Oct 29 '22 15:10

ianpetzer