Angular 2路由:防止URL更改

时间:2017-05-15 13:06:06

标签: javascript angular angular2-routing

我是Angular 2的新手。我有一个组件和一个路由模块。基本上,我试图遵循Angular routing tutorial)。它几乎可以工作(好吧,内容按预期显示)。问题是,一旦我使用了URL(例如,为了简单起见,手动输入http://localhost:4200/items/1),它就会重写http://localhost:4200的URL,然后才能说出#3; Jack Robinson" ,页面本身正确显示。我更喜欢"正常"行为(即没有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);
  }
}

"项目"的路由模块:

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)

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

修改

事实证明,错误消息 与问题相关。通过用静态假人替换我的模板,我得到了一切。而且我更加困惑。

1 个答案:

答案 0 :(得分:1)

好的,解决了。

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

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

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

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

一旦错误消息消失,路由也会按预期运行。

@MichaelPalmer,谢谢你指点我正确的方向!