It doesn’t depend on Dispatcher, so you can use it without Flux.
If I add more stuff, it will be with options, so it won’t affect the default behaviour.
It is difficult to answer. If you are using an object-tree, then the Stores as “classes” lose sense. They become just functions which mutate state. Redux does a good job explaining this.
In Flux views should only render the app state. But as many things, it depends on the component and how it is going to be used. I think unless you want to share it with the rest of the world like a black-box component, then logic should go outside.
If different parts of your app are going to be able to play, pause or stop videos (for example) that functionality should be in a Store which controls their state. The component should only care about the rendering part, it shouldn’t care if a menu has been opened and the video should pause, for example. Only -> state: “paused”. Then -> state: “playing”.
With the new Dispatcher version (1.1.0) the dispatcher accepts an string as first argument:
Template.circuit.events({
'click #switch' : function () {
Dispatcher.dispatch('CIRCUIT_TOGGLE');
}
});
Note that it will be added to type instead of the old actionType (yep, we switched to Redux style, it’s simpler).
For Stores, I wouldn’t create them inside Templates. I will create a folder and individual files for each one of them.
Then, inside stores/circuitStore.js I would do:
// Set default state needed by this store using the MeteorFlux AppState package.
AppState.set('circuit.closed', false);
Dispatcher.register(function(action) {
switch (action.type) {
case 'CIRCUIT_TOGGLE':
let currentState = AppState.get('circuit.closed');
AppState.set('circuit.closed', !currentState); // reverse state.
break;
}
});
// Link states using Tracker
Tracker.autorun(function(){
let meta = AppState.get('circuit.closed') 'light on' : 'light off';
AppState.set('circuit.meta', meta);
});
Note here we changed to payload.actionType to action.type. Again, it’s Redux style.
Then, with AppState you don’t need to create a helper anymore. You can just use {{#if circuit.closed}} and {{circuit.meta}} wherever you want.
Doing it this way the code you need is reduced significantly.
If you want to test this code just dispatch "CIRCUIT_TOGGLE" and test the state with AppState.get. You don’t need access to the function itself.
I was working from previous stuff I’d done, and I stuck your dispatcher and AppState into what I’d roughly be doing with my own solution. Part of my thinking in putting them inside the template,
architectural simplicity, fitting into the exiting Meteor model that everyone knows
ensure they are available when needed
access to the template instance
to use other aspects, e.g. data model, parents and so on (although this may be wrong headed in terms of flux)
also, to lock the store into the template
So, i’d be interested in your thoughts about that.
So with this Flux architecture, does it make more sense to subscribe to publications in the AppState then? E.g.:
AppState.set('appointments', {
handle: Meteor.subscribe('appointments'),
dataReady: this.handle.ready(), // this is probably wrong - how do we refer to handle?
});
Yes, AppState is meant to be global and hold all the state of the app in a unique object tree. The concept is similar to Baobab, NuclearJS or Redux, but prepared to play nice with Meteor reactivity, Mongo cursors, Blaze…
If you want to keep the state local to the stores, you can use things like local ReactiveVar, ReactiveDict, the excellent ReactiveObj object of @xamfoo, the upcoming Store class of @gunnarsturla or even local copies of AppState created using MeteorFlux:
A good practice of other flux frameworks using a single state object is to store only the smallest amount of state possible so I wouldn’t store the whole handle.
If your subscription depends on the application state (i.e. is part of the business logic), then I think you should subscribe in your Store (or whatever name you call the place where your business logic is).
If your subscription depends on the template (i.e. you need those data now for displaying in this template), then I think you should use template-level subscription.