手动更改路由参数导致用户界面不一致
Manually changing the route parameters leads to inconsistent user interface
这里有一个 plunker 可以玩:
https://plnkr.co/edit/qTjftING3Hk2fwN36bQa?p=preview
一切正常,除非您手动 更改 url 栏中的 id 参数,因为那时项目下拉列表不会将新 projectId 显示为当前项目。当用户将 url 保存为收藏夹 link 并将其 copy/paste 保存到 url 栏时,就会发生这种情况!我会说一个常见的情况!
为了解决这个问题,我可以监听 TestsListComponent
中的 route.params 变化,并添加一个 sharedService/EventEmitter
检查,以确定下拉列表中是否存在更改的 ID。 TestsListComponent 中的 bool return 值 existsProjectId 决定我是否应该重定向到 /projects
页面,因为该 ID 不存在。
但老实说,至少从用户体验的角度来看,从 TestsListComponent
重定向为时已晚,因为 route projects/:id/tests
已经激活。
你会如何纠正这种不当行为?
P.S.
也许有一种全局参数更改我可以监听并检查 ProjectsListComponent 中的路径及其 ID,这会有所帮助!
如果有人知道如何在 window 模式下编辑 plunkr 的 url 栏来测试这种不一致,请告诉我你是如何做到只读的 url bar editable...即使将 url 复制到新选项卡中也不起作用,因为我收到 plunkr not found 错误...=>
回答
- 加载 plunkr 并激活 window 模式
- 在window模式下copy/paste进入新标签url
- 粘贴时url:https://run.plnkr.co/LhwcQjzWHsRUda8H/projects/1/schoolclasses
- 让它成为 url:
https://run.plnkr.co/LhwcQjzWHsRUda8H/#/projects/1/schoolclasses
- 并更改参数:
https://run.plnkr.co/LhwcQjzWHsRUda8H/#/projects/2/schoolclasses
- 如果您不添加哈希,则会收到未找到的 404。
没有可以订阅的全局参数更改。
一种方法是从根路由器开始定位路由及其参数:
console.log('router', this.router.routerState.root.firstChild.firstChild && this.router.routerState.root.firstChild.firstChild.snapshot.params);
这可以在 this.router.events.subscribe((val) => {
或 canActivate
或 resolve
https://angular.io/docs/ts/latest/guide/router.html#!#guards
之类的路由器防护中完成
像下面这样更新您的 app.routes.ts 文件并使用 HashLocationStrategy,以供参考:HashLocationStrategy
import {Routes, RouterModule} from '@angular/router';
import ProjectListComponent from './projects-list.component';
import TestsListComponent from './tests-list.component';
import OverviewComponent from './overview.component';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
export const routes: Routes = [
{ path: '', redirectTo: 'projects', pathMatch: 'full' },
{
path: 'projects', component: ProjectListComponent,
children: [
{ path: ':id', redirectTo: ':id', pathMatch: 'full' },
{
path: ':id', component: OverviewComponent,
children: [
{ path: '', redirectTo: 'tests', pathMatch: 'full' },
{ path: 'tests', component: TestsListComponent },
]
]
}
];
export const appRoutingProviders: any[] = [
{
provide: LocationStrategy,
useClass: HashLocationStrategy
}
];
export const routing = RouterModule.forRoot(routes);
我不确定我是否正确理解了你的问题,无论如何这是我的plunkr。
this.router.events.subscribe(event => {
if (event instanceof RoutesRecognized)
{
var first=event.state.root.firstChild.firstChild;
var id = first && event.state.root.firstChild.firstChild.params['id'];
console.debug('recognized', id);
this.currentProject = this.projects[+id-1];
console.log(this.currentProject);
}
});
只需导航到 #/projects/1/tests
。
这里有一个 plunker 可以玩:
https://plnkr.co/edit/qTjftING3Hk2fwN36bQa?p=preview
一切正常,除非您手动 更改 url 栏中的 id 参数,因为那时项目下拉列表不会将新 projectId 显示为当前项目。当用户将 url 保存为收藏夹 link 并将其 copy/paste 保存到 url 栏时,就会发生这种情况!我会说一个常见的情况!
为了解决这个问题,我可以监听 TestsListComponent
中的 route.params 变化,并添加一个 sharedService/EventEmitter
检查,以确定下拉列表中是否存在更改的 ID。 TestsListComponent 中的 bool return 值 existsProjectId 决定我是否应该重定向到 /projects
页面,因为该 ID 不存在。
但老实说,至少从用户体验的角度来看,从 TestsListComponent
重定向为时已晚,因为 route projects/:id/tests
已经激活。
你会如何纠正这种不当行为?
P.S.
也许有一种全局参数更改我可以监听并检查 ProjectsListComponent 中的路径及其 ID,这会有所帮助!
如果有人知道如何在 window 模式下编辑 plunkr 的 url 栏来测试这种不一致,请告诉我你是如何做到只读的 url bar editable...即使将 url 复制到新选项卡中也不起作用,因为我收到 plunkr not found 错误...=> 回答
- 加载 plunkr 并激活 window 模式
- 在window模式下copy/paste进入新标签url
- 粘贴时url:https://run.plnkr.co/LhwcQjzWHsRUda8H/projects/1/schoolclasses
- 让它成为 url: https://run.plnkr.co/LhwcQjzWHsRUda8H/#/projects/1/schoolclasses
- 并更改参数: https://run.plnkr.co/LhwcQjzWHsRUda8H/#/projects/2/schoolclasses
- 如果您不添加哈希,则会收到未找到的 404。
没有可以订阅的全局参数更改。
一种方法是从根路由器开始定位路由及其参数:
console.log('router', this.router.routerState.root.firstChild.firstChild && this.router.routerState.root.firstChild.firstChild.snapshot.params);
这可以在 this.router.events.subscribe((val) => {
或 canActivate
或 resolve
https://angular.io/docs/ts/latest/guide/router.html#!#guards
像下面这样更新您的 app.routes.ts 文件并使用 HashLocationStrategy,以供参考:HashLocationStrategy
import {Routes, RouterModule} from '@angular/router';
import ProjectListComponent from './projects-list.component';
import TestsListComponent from './tests-list.component';
import OverviewComponent from './overview.component';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
export const routes: Routes = [
{ path: '', redirectTo: 'projects', pathMatch: 'full' },
{
path: 'projects', component: ProjectListComponent,
children: [
{ path: ':id', redirectTo: ':id', pathMatch: 'full' },
{
path: ':id', component: OverviewComponent,
children: [
{ path: '', redirectTo: 'tests', pathMatch: 'full' },
{ path: 'tests', component: TestsListComponent },
]
]
}
];
export const appRoutingProviders: any[] = [
{
provide: LocationStrategy,
useClass: HashLocationStrategy
}
];
export const routing = RouterModule.forRoot(routes);
我不确定我是否正确理解了你的问题,无论如何这是我的plunkr。
this.router.events.subscribe(event => {
if (event instanceof RoutesRecognized)
{
var first=event.state.root.firstChild.firstChild;
var id = first && event.state.root.firstChild.firstChild.params['id'];
console.debug('recognized', id);
this.currentProject = this.projects[+id-1];
console.log(this.currentProject);
}
});
只需导航到 #/projects/1/tests
。