Angular 2 路由:防止URL改变

Angular 2 routing: prevent URL from changing

我是新手Angular 2. 我有一个组件和一个路由模块。基本上,在我可以说 "Jack Robinson" 之前,我试图遵循 Angular routing tutorial). It almost works (well, the content is displayed as intended). The problem is that once I use an URL (say, manually enter http://localhost:4200/items/1, for the sake of simplicity), it rewrites the URL to http://localhost:4200,同时页面本身显示正确。我更喜欢 "normal" 行为(即没有 URL 更改,浏览器的后退按钮将我带到上一页等)。

我错过了什么?

我的问题组件:

import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';

import 'rxjs/add/operator/switchMap';

import { ItemService } from './item.service';
import { Item } from './item';


@Component({
  selector: 'item-details',
  templateUrl: './item-detail.component.html',
})
export class ItemDetails  {
  item : Item;
  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private service: ItemService,
  ) {}

  ngOnInit() : void {
    this.route.params
    .switchMap((params : Params ) => this.service.getItem(+params['id']))
    .subscribe((item : Item) => this.item = item);
  }
}

"items" 的路由模块:

import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { ItemsComponent }    from './items.component';
import { ItemDetails }    from './item-detail.component';

const itemRoutes: Routes = [
  { path: 'items', component: ItemsComponent },
  { path: 'items/:id', component: ItemDetails },
];

@NgModule({
  imports: [RouterModule.forChild(itemRoutes)],
  exports: [RouterModule]
})
export class ItemsRoutingModule{}

顶级路由模块:

import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { Http404 } from './Http-404';

const routes: Routes = [
  { path: '', redirectTo: 'items', pathMatch: 'full'},
  { path: '**', component: Http404 },

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule{}

来自控制台的错误消息(可能无关紧要,因为 Item 的实例已正确呈现):

ng:///ItemsModule/ItemDetails.ngfactory.js:24 ERROR TypeError: Cannot read property 'descr' of undefined
    at Object.eval [as updateRenderer] (ng:///ItemsModule/ItemDetails.ngfactory.js:100)
    at Object.debugUpdateRenderer [as updateRenderer] (vendor.bundle.js:13619)
    at checkAndUpdateView (vendor.bundle.js:12924)
    at callViewAction (vendor.bundle.js:13282)
    at execComponentViewsAction (vendor.bundle.js:13214)
    at checkAndUpdateView (vendor.bundle.js:12925)
    at callViewAction (vendor.bundle.js:13282)
    at execEmbeddedViewsAction (vendor.bundle.js:13240)
    at checkAndUpdateView (vendor.bundle.js:12920)
    at callViewAction (vendor.bundle.js:13282)

我希望这是与问题相关的所有代码。如果没有,请告诉我。提前致谢。

编辑:

事实证明,错误消息 与问题相关。通过用静态虚拟人替换我的模板,我使一切正常。更让我不解的是

好的,解决了。

主要经验教训:如果在您的 Angular 2 应用程序中出现任何其他异常,即使是暂时的,它也可能无法挽回地破坏路由部分。

问题与路由本身无关。罪魁祸首是在组件模板中使用异步获取(通过 REST API)对象,而不检查对象是否存在。由于对象不是立即从外部 REST 服务中检索到的,因此会多次发出有关未定义对象的错误消息,直到获得对象并成功呈现组件。但这足以打破路由!

因此,解决方案是将对象的 **ngIf 条件添加到组件的模板中:

<table  *ngIf="item">
  <tr>
    <td>
      Item description
    </td>
    <td>
      {{item.descr}}
    </td>
...

错误消息消失后​​,路由也按预期运行。

@MichaelPalmer,谢谢你给我指明了正确的方向!