如何使用Angular UI Router设置默认子视图

时间:2014-02-23 21:51:58

标签: javascript angularjs parent-child angular-ui

假设我有以下3个Angular UI路由器状态:

$stateProvider
    .state('adminCompanies', {
        abstract: true,
        url: "/admin/companies",
        template: '<div ui-view class="viewContainer" autoscroll="false" />'
    })
    .state('adminCompanies.list', {
        url: "",
        templateUrl: 'app/admin/companies/companies.list.html',
        controller: 'AdminCompaniesController'
    })
    .state('adminCompanies.detail', {
        url: "/:companyId",
        templateUrl: 'app/admin/companies/companies.detail.html',
        resolve: {
            company: function(Model, $stateParams) {
                return Model.get("/admin/companies", $stateParams.companyId);
            }
        },
        controller: 'AdminCompanyDetailController'
    })

如果adminCompanies直接转换为,我怎样才能告诉Angular UI路由器转到adminCompanies.list状态?

理想情况下,我想要的是:

$stateProvider.when('adminCompanies', 'adminCompanies.list');

在我的代码中,我希望$ state.go('adminCompanies')等同于$ state.go('adminCompanies.list')

3 个答案:

答案 0 :(得分:39)

由于您的应用程序当前已设置,因此您不需要任何明确的逻辑。当子状态具有空url属性时,它将在其父状态变为活动状态时变为活动状态。子状态的任何模板都插入到父状态模板提供的ui-view指令中。 Angular UI sample application解决了这种类型的体系结构:当导航contacts状态时,其template为其子状态提供导航布局以及不同的ui-view状态;因为contacts.list状态的url属性为"",所以当其父状态contacts导航到时,它会自动加载。这在应用程序的comments中记录:

  

使用空URL表示此子状态在其父网址被导航到时将变为活动状态。子状态的URL将自动附加到其父级的URL。所以这个州的网址是'/ contacts'(因为'/ contacts'+'')。

现在,假设您出于某种原因从不希望您的父adminCompanies州变为活跃状态。在这种情况下,您可以将该状态设置为abstract状态,如下所示:

$stateProvider
    .state('adminCompanies', {
        abstract: true,
        url: "/admin/companies",
        template: '<div ui-view class="viewContainer" autoscroll="false" />'
    })
    .state('adminCompanies.list', {
        url: "/list",
        templateUrl: 'app/admin/companies/companies.list.html',
        controller: 'AdminCompaniesController'
    })
    .state('adminCompanies.detail', {
        url: "/:companyId",
        templateUrl: 'app/admin/companies/companies.detail.html',
        resolve: {
            company: function(Model, $stateParams) {
                return Model.get("/admin/companies", $stateParams.companyId);
            }
        },
        controller: 'AdminCompanyDetailController'
    })

请注意,第3行添加了abstract: true/list

adminCompanies.list显式状态网址

这告诉Angular-UI它应该将此状态视为URL导航目的不存在。当您导航到子状态时,它仍将变为活动状态,因此它仍将使用您提供的URL来为子状态的URL添加前缀。但是,如果您尝试从另一个州导航到它,它将表现为状态不存在。因此,您还需要使用$urlRouteProvider添加对不匹配网址的处理。

$urlRouteProvider的基本用法可能如下所示:

$urlRouterProvider.otherwise("/")

只是将所有对不存在状态的调用重定向到URL为“/”的状态。假设你有一个。但是,因为某人可能尝试导航到列表视图但他们直接导航到/admin/companies,您可能应该有这样的处理程序:

$urlRouterProvider.when("/admin/companies", "/admin/companies/list");

您使用哪一个取决于您的应用程序的体系结构,但似乎对于您当前的需求,您不应该做任何事情。如果您的规范发生变化,抽象状态可能会派上用场。

答案 1 :(得分:2)

您还可以使用ui-router-default - 通过设置abstract: ".defaultChild"在父状态中定义默认子状态的模块。

这样可以使用ui-sref="parent"$state.go("parent");(这在动态创建导航栏时对我很重要)。

注意:这个和David的解决方案只有在父状态是抽象的情况下才有效 - 即父母在没有孩子活跃的情况下不能活动 - 当我们想要一个&#34;默认&#34;儿童观。

(另请参阅ui-router团队的相关讨论here。)

答案 2 :(得分:1)

在版本 1.0.0alpha0 中,他们终于可以实现!不是抽象状态的子项,新的 $ transitionsProvider ,您可以在其中定义 onBefore 挂钩。您可以根据状态选项更改行为。

例如,您可以更改&#34; abstract&#34; param行为:

 $transitionsProvider.onBefore({
    to: state => !!state.abstract
  }, ($transition$, $state) => {
    if (angular.isString($transition.to().abstract)) {
      return $state.target($transition.to().abstract);
    }
  });

并像这样使用它:

  abstract: 'abstract2.foo',  //use not boolean but exact child state

code example

取自: ui-router: Default child for abstract state