在SproutCore中直接路由到子状态时,如何设置控制器选择?

时间:2013-05-22 17:40:43

标签: sproutcore

如果我有一条到应用程序深处的状态的路径,虽然我将直接进入内部状态,但如何确保已完成正确的控制器设置?

例如,

  • 州A.
    • 陈述a,代表路线:'a'
    • 州B.
      • 州b,代表路线:'a / b'
      • 州C.
        • 州c,代表路线:'a / b / c'
        • 州D.
          • state d,representRoute:'a / b / c / d
          • 州E

正如您所看到的,您可以直接路由到州'a','b','c'或'd',但您看不到的是通常您会通过选择一个项目进入这些状态控制器,然后将触发状态转换到更深的状态。问题是直接进入状态'd'没有设置控制器的选择

到目前为止,我已经在状态'a'中使用enterStateByRoute来设置第一个控制器的选择,然后必须在状态'b'中使用enterStateByRoute来选择第一个控制器和第二个控制器等,一直到状态'd'的enterStateByRoute,一直选择每个控制器。这非常浪费,因为我最终在每个enterStateByRoute中重复相同的代码。

设置控制器选择以匹配直接路由状态的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

一旦我意识到路由中链中的所有父状态都调用了enterStateByRoute,我就能够大大改善这种情况。这意味着如果状态'c'与路线匹配,则输入状态'A',然后输入状态'B'和状态'C',最后进入状态'c'。我之前没有意识到的是,这些状态中的每一个都在传入SC.StateRouteHandlerContext对象时被传递,允许您检查enterState中的上下文或在任何一个中实现enterStateByRoute的状态。

我的解决方案是将enterStateByRoute添加到状态'A'以设置第一个控制器,将enterStateByRoute添加到状态'B'以设置第二个控制器等。例如,以这种方式,任何州的过去状态'A'都保证有第一个控制器选择集,我没有任何重复的代码链。

例如,

// … 
state_A: SC.State.extend({
  initialSubstate: 'state_a',

  enterStateByRoute: function (context) {
    // select object on controller 1 since we are routing
  },

  state_a: SC.State.extend({
    representRoute: 'a',

    enterStateByRoute: function (context) {
      // do setup for state 'a' specific to routing
    }
  }),

  state_B: SC.State.extend({
    initialSubstate: 'state_b',

    enterStateByRoute: function (context) {
      // select object on controller 2 since we are routing
    },

    state_b: SC.State.extend({

      enterStateByRoute: function (context) {
        // do set up for state 'b' specific to routing
      },
// …

我遇到的唯一问题是因为我将所有控制器绑定在一起,所以选择更改不会立即传播,所以我会在第一个状态的控制器上选择一个对象,进入下一个状态并找到绑定控制器的内容尚未更新。

所以我可以通过返回SC.Async中的enterStateByRoute对象并使用this.invokeLast(function () { this.resumeGotoState(); })在运行循环结束时转到下一个状态来等待刷新绑定,我采用了一种声明式方法,只需在进入/退出相应状态时设置/取消设置每个控制器的内容。