3

関数の定義とオブジェクトのインスタンス化の順序に問題があります。以下を参照してください: 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 
    }
  });

助けてくれてありがとう。

4

4 に答える 4

1

を使用しtry/catchて、最初の未定義を回避できます。

try {
    $("back-btn").disabled = fsm.can("back");
    $("next-btn").disabled = fsm.can("next");
} catch(e){}

さらに、JSFiddle内ですべてをテストしている場合は、JSをwindow.onload関数にラップします。したがって、ボタンをクリックすると、その関数のスコープ内で定義されているorfsm.back()を呼び出そうとします。それらのボタンがアクセスできる範囲内ではありません。fsm.next()fsmwindow.onload

于 2013-02-10T01:26:55.703 に答える
1

onintro指定しているコールバックの 1 つがであり、おそらくすぐに実行されるため、タイミングの問題が発生しているようです。コールバックの実装をリファクタリングすることは実用的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.
于 2013-02-10T01:06:40.063 に答える
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();
}

そしてフィドル

于 2013-02-10T05:19:29.753 に答える
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),
}
于 2013-02-10T06:10:32.080 に答える