Angular 2ルーティングで、私がルーティングしているコンポーネントのngOnInit
が2度呼び出され、ブラウザのルートが元のルート。Angular2ルーティングの問題とngOnInitが2回呼び出されました
私はMaintenanceModule
にNotificationListComponent
とNotificationEditComponent
を持っています。
私のルートAppModule
には、マップされていないルートを/maintenance/list
にリダイレクトするようにRouterModule
を設定しました。
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
ルートをたどる、と私はリストに私の通知のすべてを見ることができます。
@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;
}
}
通知リスト:リスト内の各通知について、私のNotificationListComponent
通知list.component.tsにedit(id: number)
メソッドにバインドされたそのclick
イベントがあり、編集アイコンがあり、
<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)
方法はに移動する必要があります .component.html /maintenance/edit/:id
ルート。アイコンをクリックしてそのルートに移動すると、ブラウザでアドレスバーの正しいルートが点滅します(例:localhost:4200/#/maintenance/edit/2
)。アドレスバーのルートはすぐにlocalhost:4200/#/maintenance/list
に戻ります。アドレスバーの/maintenance/list
にルートが返されたにもかかわらず、私のNotificationEditComponent
は実際のアプリケーションで引き続き表示されます。しかし、私はメソッドがNotificationEditComponent
で2回呼び出されていることがわかります。id
がコンソールに2回記録され、ngOnInit
関数にブレークポイントを置くと、そのブレークポイントに2回ヒットします。
通知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
);
}
}
これはまた、たとえば[(ngModel)]="notification.notificationId"
のために、使用して私のNotificationEditComponent
の値にinput
値をバインドしようとしたときので、値を他の問題を引き起こしているように見えます私はAuguryクロム拡張で見ることができますが、コンソールにオブジェクトを記録するだけでなく、コンポーネントに値が入力されているにもかかわらず、画面に表示されません。
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クロムの拡張子が付きます。ただし、テンプレートにデータが表示されず、ルートのテンプレートが表示されていても、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 **を使用しています。ワイルドカードルートがなくても、問題は引き続き発生します。 –