Reputation: 3137
I am having issues with the order of defining functions and instantiating objects, see: JSFiddle
I'm just playing around with an idea right now, but I hit this wall and I don't know if there's any simple solution to the problem. Basically I have a an object with some methods on another object, but this other object contains references to the first object and so no matter what order I instantiate/define I'll get an error because one or the other hasn't been loaded:
var router = {
update: function(event, from, to) {
window.location.hash = "#/" + to;
$("back-btn").disabled = fsm.can("back"); // *** And here I am referencing fsm
$("next-btn").disabled = fsm.can("next");
},
location: window.location.hash.substring(2),
}
var fsm = StateMachine.create({
initial: "intro",
events: [
// Next events and where to route based on our page
{ name: "next", from: "intro", to: "getname" },
{ name: "next", from: "getname", to: "welcome" },
{ name: "next", from: "welcome", to: "why" },
// We can't go "back" from the initial route
{ name: "back", from: "getname", to: "intro" },
{ name: "back", from: "welcome", to: "getname" },
{ name: "back", from: "why", to: "welcome" } ],
callbacks: {
onintro : router.update, //*** Here I am referencing the router object
ongetname: router.update,
onwelcome: router.update,
onwhy : router.update
}
});
Thanks for any help.
Upvotes: 3
Views: 115
Reputation: 2470
The dependency fix could be as simple as:
var router = {
update: function(event, from, to) {
window.location.hash = "#/" + to;
if(window.fsm) {
$("back-btn").disabled = fsm.can("back");
$("next-btn").disabled = fsm.can("next");
}
},
location: window.location.hash.substring(2),
}
Upvotes: 0
Reputation: 3137
I had to assign the callbacks to the state machine object after the fact, and then defer initialization until after my router object was defined:
var fsm = StateMachine.create({
//*** Here we set defer to true
initial: { state: "intro", event: "init", defer: true },
events: [
// Next events and where to route based on our page
{ name: "next", from: "intro", to: "getname" },
{ name: "next", from: "getname", to: "welcome" },
{ name: "next", from: "welcome", to: "why" },
// We can't go "back" from the initial route
{ name: "back", from: "getname", to: "intro" },
{ name: "back", from: "welcome", to: "getname" },
{ name: "back", from: "why", to: "welcome" } ],
});
window.onload = function() {
var router = {
update: function(event, from, to) {
window.location.hash = "#/" + to;
$("back-btn").disabled = fsm.cannot("back");
$("next-btn").disabled = fsm.cannot("next");
},
location: window.location.hash.substring(2),
}
//*** And now we attach the callbacks since we have created the router object
fsm.onintro = router.update, fsm.ongetname = router.update,
fsm.ongetname = router.update, fsm.onwelcome = router.update,
fsm.onwhy = router.update;
//*** And call the init event!
fsm.init();
}
and the fiddle
Upvotes: 1
Reputation: 2470
It looks like the timing issue occurs because one of the callbacks you are specifying is onintro
, which presumably runs right away. Is it practical to refactor your implementation for the onintro
callback? You might be able to get away with something like this:
var router = {
update: function(event, from, to) {
window.location.hash = "#/" + to;
$("back-btn").disabled = fsm.can("back");
$("next-btn").disabled = fsm.can("next");
},
location: window.location.hash.substring(2),
}
var fsm = StateMachine.create({
//...
callbacks: {
//onintro : router.update, // Don't call this in the constructor...
ongetname: router.update,
onwelcome: router.update,
onwhy : router.update
}
});
router.update(); // Call it just after construct.
Upvotes: 1
Reputation: 2674
You could use a try/catch
to avoid the first undefined:
try {
$("back-btn").disabled = fsm.can("back");
$("next-btn").disabled = fsm.can("next");
} catch(e){}
Additionally, if you're testing all within JSFiddle, it's going to wrap your JS into a window.onload
function. So when you click the buttons, they'll be trying to call fsm.back()
or fsm.next()
, where fsm
was defined within the scope of that window.onload
function. Not within the scope those buttons have access to.
Upvotes: 1