Let's say I have the following 3 Angular UI Router states:
假设我有以下3个角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'
})
If the adminCompanies
is transitioned to directly, how can I tell Angular UI Router to go to the adminCompanies.list
state instead?
如果管理员公司被直接转换为管理员,我如何告诉角UI路由器去管理员公司。列表状态呢?
Ideally, what I'd like to is something like:
理想情况下,我想做的是:
$stateProvider.when('adminCompanies', 'adminCompanies.list');
In my code, I then want $state.go('adminCompanies') to be equivalent to $state.go('adminCompanies.list')
在我的代码中,我想要$state.go('adminCompanies')等于$state。go('adminCompanies.list')
3 个解决方案
#1
38
As your application is currently set up, you should not need any explicit logic for this. When a sub-state has an empty url
property, it becomes active at the same time its parent state becomes active. Any template for the sub-state is inserted into the ui-view
directive provided by the parent state's template. The Angular UI sample application addresses this type of architecture: when the contacts
state is navigated to, its template provides the navigation layout as well as a distinct ui-view
for its sub-states; because the contacts.list
state has a url
property of ""
, it is automatically loaded when its parent state, contacts
is navigated to. This is documented in the application's comments:
由于您的应用程序目前正在设置,因此不应该为此需要任何显式逻辑。当一个子状态有一个空url属性时,它会在其父状态变为活动状态的同时变得活动。子状态的任何模板都被插入到父状态模板提供的ui-view指令中。角UI示例应用程序处理这种类型的体系结构:当联系人状态导航到它时,它的模板提供导航布局以及其子状态的独特UI视图;因为联系人。列表状态具有“”的url属性,当它的父状态被导航到时,它会自动加载。这在应用程序的注释中有记录:
Using an empty url means that this child state will become active when its parent's url is navigated to. Urls of child states are automatically appended to the urls of their parent. So this state's url is '/contacts' (because '/contacts' + '').
使用空url意味着在导航到其父url时该子状态将变为活动状态。子状态的url会自动附加到其父url。所以这个状态的url是'/contacts'(因为'/contacts' + ")。
Now, assuming for one reason or another that you never wanted your parent adminCompanies
state to become active. In this case, you can make that state an abstract state like so:
现在,假设出于某种原因,您从未希望您的父adminCompanies state变得活跃。在这种情况下,您可以使该状态成为这样的抽象状态:
$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'
})
Note the addition of the abstract: true
addition on the 3rd line and the explicit state url of /list
for adminCompanies.list
请注意第3行添加的摘要:true add以及admin .list的显式状态url /list
This tells Angular-UI that it should treat this state as if doesn't exist for URL navigation purposes. It will still become active when you navigate to sub-states though, so it will still use the URL you provide to prefix the URL of sub-states. But if you try navigating to it from another state, it will act as if the state doesn't exist. For this reason, you will also need to add handling for unmatched URLs using $urlRouteProvider
.
这就告诉Angular-UI,出于URL导航的目的,它应该将这个状态视为不存在。当您导航到子状态时,它仍然是活动的,因此它仍然使用您提供给子状态URL前缀的URL。但是如果您尝试从另一个状态导航到它,它就会表现为状态不存在。由于这个原因,您还需要使用$urlRouteProvider为不匹配的url添加处理。
A basic use of $urlRouteProvider
might look like this:
$urlRouteProvider的基本用法如下:
$urlRouterProvider.otherwise("/")
That just redirects all calls to non-existent states to the state with the URL of "/". This assumes you have one. However, because someone might be trying to navigate to the list view but they are navigating to /admin/companies
directly, you should probably have a handler like this:
它只是将所有对不存在状态的调用重定向到URL为"/"的状态。假设你有一个。然而,由于有些人可能试图导航到列表视图,但他们直接导航到/admin/companies,您可能应该有这样的处理程序:
$urlRouterProvider.when("/admin/companies", "/admin/companies/list");
Which one you use depends on the architecture of your application, but it seems that for your current needs you shouldn't have to do anything. If your specifications change, the abstract state might come in handy.
您使用哪一个取决于应用程序的体系结构,但是对于当前的需求,您似乎不需要做任何事情。如果您的规范发生变化,抽象状态可能会派上用场。
#2
2
You can also use ui-router-default - a module where default child states are defined in the parent state by setting abstract: ".defaultChild"
.
您还可以使用ui-router-default——通过设置抽象“. defaultchild”,在父状态中定义默认子状态。
This has the benefit of being able to use ui-sref="parent"
and $state.go("parent");
(which was important for me when dynamically creating a navbar).
这样做的好处是可以使用ui-sref="parent"和$state.go("parent");(这对动态创建导航条很重要)。
NB: Both this and David's solution only work if the parent state is abstract - i.e. the parent cannot be active without a child being active - which should be the case when we want to have a "default" child view.
NB:这和David的解决方案都只在父状态是抽象的情况下有效——例如,如果没有子节点是活动的,父节点就不能活动——当我们想要有一个“默认”子视图时,应该是这样。
(See also the ui-router team's relevant discussion here.)
(请参见ui-router团队的相关讨论。)
#3
1
In version 1.0.0alpha0 they finally make it possible! Not child for abstract states, new $transitionsProvider, in which you could define onBefore hook. You can change the behaviour depends on state options.
在1.0.0alpha0版本中,他们终于让这一切成为可能!不是抽象状态的子元素,而是新的$transitionsProvider,您可以在其中定义onBefore hook。您可以根据状态选项更改行为。
For example you can change "abstract" param behaviour:
例如,你可以改变“抽象”帕拉姆行为:
$transitionsProvider.onBefore({
to: state => !!state.abstract
}, ($transition$, $state) => {
if (angular.isString($transition.to().abstract)) {
return $state.target($transition.to().abstract);
}
});
and use it like so:
像这样使用它:
abstract: 'abstract2.foo', //use not boolean but exact child state
代码示例
was taken from: ui-router: Default child for abstract state
是从:ui-router:抽象状态的默认子元素吗
#1
38
As your application is currently set up, you should not need any explicit logic for this. When a sub-state has an empty url
property, it becomes active at the same time its parent state becomes active. Any template for the sub-state is inserted into the ui-view
directive provided by the parent state's template. The Angular UI sample application addresses this type of architecture: when the contacts
state is navigated to, its template provides the navigation layout as well as a distinct ui-view
for its sub-states; because the contacts.list
state has a url
property of ""
, it is automatically loaded when its parent state, contacts
is navigated to. This is documented in the application's comments:
由于您的应用程序目前正在设置,因此不应该为此需要任何显式逻辑。当一个子状态有一个空url属性时,它会在其父状态变为活动状态的同时变得活动。子状态的任何模板都被插入到父状态模板提供的ui-view指令中。角UI示例应用程序处理这种类型的体系结构:当联系人状态导航到它时,它的模板提供导航布局以及其子状态的独特UI视图;因为联系人。列表状态具有“”的url属性,当它的父状态被导航到时,它会自动加载。这在应用程序的注释中有记录:
Using an empty url means that this child state will become active when its parent's url is navigated to. Urls of child states are automatically appended to the urls of their parent. So this state's url is '/contacts' (because '/contacts' + '').
使用空url意味着在导航到其父url时该子状态将变为活动状态。子状态的url会自动附加到其父url。所以这个状态的url是'/contacts'(因为'/contacts' + ")。
Now, assuming for one reason or another that you never wanted your parent adminCompanies
state to become active. In this case, you can make that state an abstract state like so:
现在,假设出于某种原因,您从未希望您的父adminCompanies state变得活跃。在这种情况下,您可以使该状态成为这样的抽象状态:
$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'
})
Note the addition of the abstract: true
addition on the 3rd line and the explicit state url of /list
for adminCompanies.list
请注意第3行添加的摘要:true add以及admin .list的显式状态url /list
This tells Angular-UI that it should treat this state as if doesn't exist for URL navigation purposes. It will still become active when you navigate to sub-states though, so it will still use the URL you provide to prefix the URL of sub-states. But if you try navigating to it from another state, it will act as if the state doesn't exist. For this reason, you will also need to add handling for unmatched URLs using $urlRouteProvider
.
这就告诉Angular-UI,出于URL导航的目的,它应该将这个状态视为不存在。当您导航到子状态时,它仍然是活动的,因此它仍然使用您提供给子状态URL前缀的URL。但是如果您尝试从另一个状态导航到它,它就会表现为状态不存在。由于这个原因,您还需要使用$urlRouteProvider为不匹配的url添加处理。
A basic use of $urlRouteProvider
might look like this:
$urlRouteProvider的基本用法如下:
$urlRouterProvider.otherwise("/")
That just redirects all calls to non-existent states to the state with the URL of "/". This assumes you have one. However, because someone might be trying to navigate to the list view but they are navigating to /admin/companies
directly, you should probably have a handler like this:
它只是将所有对不存在状态的调用重定向到URL为"/"的状态。假设你有一个。然而,由于有些人可能试图导航到列表视图,但他们直接导航到/admin/companies,您可能应该有这样的处理程序:
$urlRouterProvider.when("/admin/companies", "/admin/companies/list");
Which one you use depends on the architecture of your application, but it seems that for your current needs you shouldn't have to do anything. If your specifications change, the abstract state might come in handy.
您使用哪一个取决于应用程序的体系结构,但是对于当前的需求,您似乎不需要做任何事情。如果您的规范发生变化,抽象状态可能会派上用场。
#2
2
You can also use ui-router-default - a module where default child states are defined in the parent state by setting abstract: ".defaultChild"
.
您还可以使用ui-router-default——通过设置抽象“. defaultchild”,在父状态中定义默认子状态。
This has the benefit of being able to use ui-sref="parent"
and $state.go("parent");
(which was important for me when dynamically creating a navbar).
这样做的好处是可以使用ui-sref="parent"和$state.go("parent");(这对动态创建导航条很重要)。
NB: Both this and David's solution only work if the parent state is abstract - i.e. the parent cannot be active without a child being active - which should be the case when we want to have a "default" child view.
NB:这和David的解决方案都只在父状态是抽象的情况下有效——例如,如果没有子节点是活动的,父节点就不能活动——当我们想要有一个“默认”子视图时,应该是这样。
(See also the ui-router team's relevant discussion here.)
(请参见ui-router团队的相关讨论。)
#3
1
In version 1.0.0alpha0 they finally make it possible! Not child for abstract states, new $transitionsProvider, in which you could define onBefore hook. You can change the behaviour depends on state options.
在1.0.0alpha0版本中,他们终于让这一切成为可能!不是抽象状态的子元素,而是新的$transitionsProvider,您可以在其中定义onBefore hook。您可以根据状态选项更改行为。
For example you can change "abstract" param behaviour:
例如,你可以改变“抽象”帕拉姆行为:
$transitionsProvider.onBefore({
to: state => !!state.abstract
}, ($transition$, $state) => {
if (angular.isString($transition.to().abstract)) {
return $state.target($transition.to().abstract);
}
});
and use it like so:
像这样使用它:
abstract: 'abstract2.foo', //use not boolean but exact child state
代码示例
was taken from: ui-router: Default child for abstract state
是从:ui-router:抽象状态的默认子元素吗