我有一個非常奇怪的問題,與Angular 2路由到我的路由組件中的ngOnInit
被調用兩次,並且瀏覽器中的路由被重置爲原始路線。Angular2路由問題和ngOnInit調用兩次
我有一個NotificationListComponent
和一個NotificationEditComponent
在MaintenanceModule
。
在我的根目錄AppModule
中,我設置了RouterModule
將任何未映射的路線重定向到/maintenance/list
。
app.module.ts:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot([
{path: "", redirectTo: "maintenance/list", pathMatch: "full"},
{path: "**", redirectTo: "maintenance/list", pathMatch: "full"}
], {useHash: true}),
CoreModule.forRoot({notificationUrl: "http://localhost:8080/notification-service/notifications"}),
MaintenanceModule
],
providers: [NotificationService],
bootstrap: [AppComponent]
})
export class AppModule { }
我有我的NotificationListComponent
在我MaintenanceModule
定義的/maintenance/list
路線,這點,以及指向我NotificationEditComponent
一個/maintenance/edit/:id
路線。
maintenance.module.ts:
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{path: "maintenance/list", component: NotificationListComponent, pathMatch: 'full'},
{path: "maintenance/edit/:id", component: NotificationEditComponent, pathMatch: 'full'}
]),
FormsModule
],
declarations: [
NotificationListComponent,
NotificationEditComponent
]
})
export class MaintenanceModule {}
當我的應用程序負載,它正確地遵循/maintenance/list
路線,我可以看到列表中的所有我的通知。對於列表中的每個通知有一個編輯圖標,它有它在我的NotificationListComponent
通知,list.component.ts綁定到edit(id: number)
方法click
事件:
@Component({
templateUrl: 'notification-list.component.html'
})
export class NotificationListComponent implements OnInit {
notifications: Notification[];
errorMessage: string;
constructor(private _notificationService: NotificationService,
private _router: Router) {}
ngOnInit(): void {
this._notificationService.getNotifications()
.subscribe(
notifications => this.notifications = notifications,
error => this.errorMessage = <any>error);
}
clearError(): void {
this.errorMessage = null;
}
}
通知列表.component.html:
<div class="row">
<h1>Notification Maintenance</h1>
<div *ngIf="errorMessage" class="alert-box alert">
<span>{{errorMessage}}</span>
<a class="right" (click)="clearError()">×</a>
</div>
<p-dataTable [value]="notifications" [sortField]="'code'" [responsive]="true" [sortOrder]="1" [rows]="10" [paginator]="true" [rowsPerPageOptions]="[10,50,100]">
<p-header>Available Notifications</p-header>
<p-column [field]="'code'" [header]="'Code'" [sortable]="true" [style]="{'width':'10%'}"></p-column>
<p-column [field]="'name'" [header]="'Name'" [sortable]="true" [style]="{'width':'40%'}"></p-column>
<p-column [field]="'roles'" [header]="'Roles'" [style]="{'width':'40%'}"></p-column>
<p-column [field]="'notificationId'" [header]="'Edit'" [style]="{'width':'10%'}">
<template let-row="rowData" pTemplate="body">
<a [routerLink]="'/maintenance/edit/' + row['notificationId']"><span class="fa fa-pencil fa-2x"></span></a>
</template>
</p-column>
</p-dataTable>
</div>
正如你所看到的,edit(id: number)
方法應該定位到/maintenance/edit/:id
路線。當我點擊圖標導航到該路線時,瀏覽器會在地址欄中閃爍正確的路線(例如localhost:4200/#/maintenance/edit/2
),但地址欄中的路線會立即變回localhost:4200/#/maintenance/list
。即使路由在地址欄中返回到/maintenance/list
,我的NotificationEditComponent
仍然在實際應用程序中可見。但是,我可以看到ngOnInit
方法在我的NotificationEditComponent
中被調用了兩次,因爲id
被記錄到控制檯兩次,並且如果我在ngOnInit
函數中放置了斷點,它會兩次觸發該斷點。
通知-edit.component.ts:
@Component({
templateUrl: "notification-edit.component.html"
})
export class NotificationEditComponent implements OnInit{
notification: Notification;
errorMessage: string;
constructor(private _notificationService: NotificationService,
private _route: ActivatedRoute,
private _router: Router) {
}
ngOnInit(): void {
let id = +this._route.snapshot.params['id'];
console.log(id);
this._notificationService.getNotification(id)
.subscribe(
notification => this.notification = notification,
error => this.errorMessage = <any>error
);
}
}
這似乎也可能會導致其他問題,因爲當試圖綁定我NotificationEditComponent
使用input
值值,例如[(ngModel)]="notification.notificationId"
,值沒有顯示在屏幕上,儘管我可以用Augury chrome擴展名來看,也可以將對象記錄到控制檯,該值被填充到組件中。
notification-edit.component。HTML:
<div class="row">
<h1>Notification Maintenance</h1>
<div *ngIf="errorMessage" class="alert-box alert">
<span>{{errorMessage}}</span>
<a class="right" (click)="clearError()">×</a>
</div>
<p-fieldset [legend]="'Edit Notification'">
<label for="notificationId">ID:
<input id="notificationId" type="number" disabled [(ngModel)]="notification.notificationId"/>
</label>
</p-fieldset>
</div>
沒有人有任何想法,爲什麼這會發生?
更新:
我刪除了我的電話給NotificationService
,與只是一些模擬數據替換它們,然後路由開始工作!但是,只要我將呼叫添加到我的服務中,我就會遇到與上述相同的問題。我甚至刪除了CoreModule
,並直接將該服務添加到我的MaintenanceModule
,並且每當我使用實際服務而不是僅模擬數據時仍然遇到同樣的問題。
notification.service.ts:
@Injectable()
export class NotificationService {
private _notificationUrl : string = environment.servicePath;
constructor(private _http: Http) {
}
getNotifications(): Observable<Notification[]> {
return this._http.get(this._notificationUrl)
.map((response: Response) => <Notification[]>response.json())
.catch(this.handleGetError);
}
getNotification(id: number): Observable<Notification> {
return this._http.get(this._notificationUrl + "/" + id)
.map((response: Response) => <Notification>response.json())
.catch(this.handleGetError);
}
postNotification(notification: Notification): Observable<number> {
let id = notification.notificationId;
let requestUrl = this._notificationUrl + (id ? "/" + id : "");
return this._http.post(requestUrl, notification)
.map((response: Response) => <number>response.json())
.catch(this.handlePostError);
}
private handleGetError(error: Response) {
console.error(error);
return Observable.throw('Error retrieving existing notification(s)!');
}
private handlePostError(error: Response) {
console.error(error);
return Observable.throw('Error while attempting to save notification!');
}
}
,服務似乎運行正常 - 我可以看到,端點成功返回數據,我可以看到,當我看數據看起來是正確的我與Augury鉻擴展的NotificationEditComponent
。但是數據不會顯示在模板中,並且即使仍顯示/maintenance/edit/:id
路由的模板,URL中的路由也會返回到/maintenance/list
。
更新2:
至於建議由@ user3249448,我增加了以下我AppComponent
一些調試:
constructor(private _router: Router) {
this._router.events.pairwise().subscribe((event) => {
console.log(event);
});
}
這裏是一個輸出,當我點擊「編輯之一「鏈接:
您使用的是最新的Angular2版本嗎?前段時間有一個問題導致了這種行爲,但之前AFAIR被修復了。 –
嘗試刪除通配符路由並查看問題是否消失。我記得閱讀有關通配符路由需要在列表中的最後一個,我不太確定在你的配置情況。 – wolfhoundjesse
我使用** 2.4.8 **和'@ angular/router'版本** 3.4.8 **。即使沒有通配符路由,問題仍然存在。 –