我遇到定义函数和实例化对象的顺序问题,请参阅:JSFiddle
我现在正在尝试一个想法,但我碰到了这堵墙,我不知道是否有任何简单的解决方案。基本上我有一个对象在另一个对象上有一些方法,但是这个另一个对象包含对第一个对象的引用,所以无论我实例化/定义什么顺序我都会得到一个错误,因为一个或另一个没有被加载:
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
}
});
感谢您的帮助。
答案 0 :(得分:1)
看起来计时问题是因为您指定的其中一个回调是onintro
,可能会立即运行。重构onintro
回调的实现是否切实可行?你可能会得到这样的东西:
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.
答案 1 :(得分:1)
您可以使用try/catch
来避免第一个未定义:
try {
$("back-btn").disabled = fsm.can("back");
$("next-btn").disabled = fsm.can("next");
} catch(e){}
此外,如果你在JSFiddle中测试所有内容,它会将你的JS包装成window.onload
函数。因此,当您点击按钮时,他们会尝试拨打fsm.back()
或fsm.next()
,其中fsm
是在window.onload
功能的范围内定义的。不在这些按钮可以访问的范围内。
答案 2 :(得分:1)
我必须在事后将回调分配给状态机对象,然后将初始化推迟到我的路由器对象定义之后:
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();
}
答案 3 :(得分:0)
依赖项修复可能很简单:
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),
}