相同的控制器,相同的模板,相同的资源,但一个是嵌套状态而另一个不是

时间:2015-07-08 15:19:50

标签: javascript angularjs angular-ui-router

在我的申请表上,我有课程和活动。有两种显示事件的方式(这里是有问题的状态):

一个是访问本周的活动('活动'州):

.state('events.show',
  url: '/events/:eventId'
  views:
    '@':
      templateUrl: '<%= asset_path('events/show.html') %>'
      controller: 'EventCtrl'
  resolve: { event: EventResolver }
)

另一个当我从作为课程范围的事件列表中选择时:

.state('courses.show.event',
  url: '/events/:eventId'
  views:
    '@':
      templateUrl: '<%= asset_path('events/show.html') %>'
      controller: 'EventCtrl'
  resolve: { event: EventResolver }
)

由于重复,这看起来真的是一种不好的做法,但我不知道我该怎么做呢,因为我想保留一个&#34; Back&#34; events/show.html模板中的按钮可以返回到作用域事件列表,也可以返回到本周的事件,具体取决于用户访问资源的位置。

是否有更好的方法来保持&#34;返回&#34;没有所有这些复制按钮去我想要的地方?我应该采用不同的方法吗?

1 个答案:

答案 0 :(得分:1)

如果要废弃复制,可以使用状态对象定义。

var eventsState = {
  url: '/events/:eventId'
  views:
    '@':
      templateUrl: '<%= asset_path('events/show.html') %>'
      controller: 'EventCtrl'
  resolve: { event: EventResolver }  
};


$stateProvider
  .state('events.show', eventsState)
  .state('courses.show.event', eventsState)

就我而言,这将是阻力最小的道路,但很难说出最好的前进方式是什么 - 没见过整个州树。

可以使用相关视图中的resolve属性将返回到您来自哪个州的后退按钮注入控制器。

views: 
  '@': 
    templateUrl: '....'
    resolve: {
      stateOpener: function ($state) {
        /** 
         * $state does _not_ refer to the $state you transitioned to, 
         * but the $state you came from.
         */
        return $state.current.name;
      }
    },
    controller: function ($scope, $state, stateOpener) {
      $scope.goBack = function () {
        $state.go(stateOpener);
      };
    }

你也可以查看ui-router-extras#previousState,这可能是让你的后退按钮走到哪里的最干净的方式。

当然,有$window.history这样做的方式,但是(imho)你应该坚持在状态机领域而不是浏览器历史中工作。