0

I'd like to implement this statechart in Ember.js v1.5.x using Ember.Router, but I have problems with the concurrency and history mechanism.

Basically when I activate the Summary route/state I'd like to transition to No changes made and Transient state in the same time. How can I achieve this?

P.S. I know that e.g. stativus have these capabilities but don't know how to use it with Ember.js routing. An example would bee good.

(image source: Ian Horrocks: Constructing the User Interface With Statecharts p.153).

apreg
  • 637
  • 8
  • 18

1 Answers1

1

:)

Yeah statecharts are lovely and all, but Ember actually affords sub-states through computed properties.

I'm not overly familiar with state charts, and I'd really need to consume the resources (horrocks) you mentioned here (https://github.com/emberjs/ember.js/issues/4767#issuecomment-41458710) before I'd be fully conversant in the nomenclature of that particular example (which I can do if you'd like).

To that end, and having said that, please take my answer with a grain of salt, because I may not fully understand the context. I just hope to help.

So in Ember you have routes. Those routes explain the interface of your application. These will effectively be your states. Routes are not your actions, or events. They provide a URL for your app to present itself to the world.

So, state A seems to be presenting the Students. You have two sub-states in there... 0 students and >0 students. You would handle these with the same Route (call it StudentsRoute), because they're both about the same set of data, just different substates of it. The route would have a path called /students probably. At that point, you'd have a controller gets fed a model by the router (the list of students), so to that end, this controller would be an extension of Em.ArrayController.

This array controller (auto-named StudentsController, extends Em.ArrayController) automatically has a 'model', and that model, once resolved, is the students "array".

In StudentsController, you could easily have a computed property called zeroCount which represents the state of zero or not about the model. Computed properties automatically stay up to date. That'd be defined like this:

App.StudentsController = Em.ArrayController.extend({
  zeroCount: function() {
  // zeroCount is true if zero, otherwise false
    return this.get('model.length') == 0;
  }.property('model.length');
});

In your students template, you could conditionally render one of two sub-templates depending on this zeroCount state... you'd do that like this:

{{#if zeroCount}}
  {{partial "noStudents"}}
{{else}}
  {{partial "someStudents"}}
{{/if}}

Mind you, for this example, that'd be somewhat overkill... you probably don't need to render other templates (partials) like that.. there's an easier simpler way to do it because this is a common pattern in ember (rendering a list, and optionally rendering something else if there are no items in it, without needing the zeroCount property).

{{#each model}}
  <p>This renders against each student... <br>
  so if your students have a property called name, <br>
  then you could just write {{name}} and it'd render the
  students name</p>
{{else}}
  <p>This renders when there are no students</p>
{{/each}}

You'd put a delete link on each of those items... and the live bound properties handle all the states for you... (thus, when model has zero items in it, the template goes into the else block of the each... otherwise it goes into the main block).

The delete action, handled by something like Delete inside your #each model template (handlebars) directive goes to the controller and looks for an action inside of it called, unsurprisingly, delete... and that'd look like this:

App.StudentsController = Em.ArrayController.extend({
  actions: {
    delete: function(itemToDelete) {
      itemToDelete.delete();
      // assuming the model "class" understands delete
    }
  }
});

The edit state would have its own route... possibly a nested route on the students, called edit, possibly not depending on if you wanted the list to appear on the screen while the edit page appears...

The "changes made" state is effectively handled not on the route, but on the model... as it should be... the model is responsible for persisting the object graph, or telling the view and controller whether or not the model has changed (Ember Data, for example, afford isDirty as a state on each model instance that can tell you whether it has changed or not)...

Hopefully this whets your appetite. I recommend going through some of the examples on the Ember site... they really do help, and following the Ember TODOMVC app if you haven't checked that out...

Ember thrives on these kind of flow-based state driven UIs... check out Tom and Yehuda's keynote at confreaks if you haven't already... they talk about flows in exactly the same way you're talking about these states and sub-states.

Hope that helps.

Julian Leviston
  • 1,646
  • 10
  • 21
  • Or my talk, Controlling Route Traversal with Flows: http://confreaks.com/videos/3312-emberconf2014-controlling-route-traversal-with-flows :) – nathanhammond Apr 26 '14 at 04:42
  • Nice! :-) this wasn't up when I last looked, yesterday ;-) It's been really nice seeing the videos from the conf. I wish I'd had the chance to be there. – Julian Leviston Apr 26 '14 at 05:40
  • @nathanhammond I'm going to recommend this to someone else I've been trying to help with routing recently... thanks. <3 – Julian Leviston Apr 26 '14 at 05:43
  • Heya @apreg did my answer help you or solve your problem? If so, could you either accept it, or if you have any more information about a better solution, answer it yourself? – Julian Leviston Apr 27 '14 at 05:29
  • Sorry, I was hesitating to accept it although it solves this problem because I'm not sure if it is always a good thing to handle concurrent states this way but I cannot come up with a situation which could enlighten this (maybe there is not one at all). I also felt that handling the state changes would fit better in the model. So, all in all, I accept it. Thank you for your help. – apreg Apr 28 '14 at 07:00
  • Did you take a look at nathanhammond's talk? Did it not address your issues somewhat? I thought it was pretty pertinent, but maybe I need to read that book you were referencing :) Do you think so? – Julian Leviston Apr 29 '14 at 02:46
  • I think application state is substantially different from business model state, btw and the model should be where the business model state is. In ember, the router handles most of the application state. (Mapping URLs into application logic) – Julian Leviston May 05 '14 at 07:54