sebpiq / backbone.statemachine

Simple finite-state machine for Backbone. View states made easy. Synchronizing your application's parts with events made easy.
MIT License
177 stars 16 forks source link

Better support for initial state #8

Closed sebpiq closed 12 years ago

sebpiq commented 12 years ago

For the moment, nothing is done automatically when starting your state machine with an initial state. This causes a pb for example with StatefulView, because the initial css class is not set.

sebpiq commented 12 years ago

Why not having a built-in 'init' state like a good state machine ?

cgarvis commented 12 years ago

Maybe just a paramater of initial: true on the state?

cgarvis commented 12 years ago

Or have an option for the StatefulView to bind to a model field.

cgarvis commented 12 years ago

Some documentation on the fact that you have to explicitly set the currentState in the initialize and not pass it in the options would help.

sebpiq commented 12 years ago

Hi Christopher. Thanks for all the comments (especially the jslint, I've been intending to do that for quite a while). I'm having a very busy week, but I'll come back to all this very quickly.

cgarvis commented 12 years ago

My current setup for initial state is

var View = Backbone.StatefulView.extend({
  initialize: function(options) {
    this.currentState = this.model.get('state');
    Backbone.StatefulView.prototype.initialize.call(this, options);
  },

  render: function() {
    this.toState(this.currentState);
    return this;
  }
});

This works well for me because I have transition callbacks for saving the model and then state enterCbs for setting up the view.

Is this how you are in visioning it working?

sebpiq commented 12 years ago

My setup is the following :


var View = Backbone.StatefulView.extend({
  initialize: function(options) {
    this.toState('init');
    Backbone.StatefulView.prototype.initialize.call(this, options);
  }
});

Basically I always put an 'init' state in my state machines, this helps for setup actions that only have to be done once. This is also quite standard with state machines in general. I don't really like this initial: true thing, because it gives you a fake impression that you don't have to initialize things yourself. I have tried before, and I had usually a lot of stuff to initialize (modifying the DOM, changing some css, ...), so basically that was useless.

I like the approach of an 'init' state much more because it solves this problem, and is coherent with the way you need to use the machine (you shouldn't have to setup stuff manually, let the transitions handle it). So I guess my favorite solution at the moment is to make the 'init' state standard (the machine would go automatically in this state if it is defined).

sebpiq commented 12 years ago

And this is actually documented, but probably not clearly enough :

// !!! For now, you also need to force it to its initial state manually
element.toState('visible');
dukejones commented 12 years ago

The Backbone.StatefulView.prototype.initialize.call(this, options); is not documented in the readme! Is StatefulView usable without this line? If not, there really should be some mention of the necessity to initialize the underlying StatefulView object.

dukejones commented 12 years ago

And I support simply having an 'init' state instead of muddying the abstraction with more stuff. That's how FSM's were when we studied them in school...

dukejones commented 12 years ago

Since StatefulView is not working for me at all, I'm just mixing the StateMachine into my View class manually. The docs don't mention the requirement to call startStateMachine() in order to kick the state machine into action.

Actually, that might be a good place to pass the initial state instead of a further toState call.

sebpiq commented 12 years ago

@dukejones : this is how the StatefulView constructor looks like : https://github.com/sebpiq/backbone.statemachine/blob/master/backbone.statemachine.js#L185

So there is no need to call Backbone.StatefulView.prototype.initialize. So if you didn't manage to get it working, there might be something wrong in what you did, or some bug in the backbone.statemachine code. In either case, it would be great if you could post some code, so that I can figure out what's wrong, help you and then fix the docs or the code !

I think I'll go for the "init" state. A bit more convention is sometimes good ! And I don't see a case where it would make things harder ...

dukejones commented 12 years ago

I'll experiment and open a new ticket for that.

sebpiq commented 12 years ago

now done in 9619b1714018740ad83b905ad80209fd4014f200