ฉันกำลังเรียกใช้router.navigate
ในหน้าเดียวกันพร้อมกับพารามิเตอร์สตริงการค้นหา ในกรณีngOnInit()
นี้ไม่โทร. เป็นค่าเริ่มต้นหรือต้องเพิ่มอะไรอีก?
ฉันกำลังเรียกใช้router.navigate
ในหน้าเดียวกันพร้อมกับพารามิเตอร์สตริงการค้นหา ในกรณีngOnInit()
นี้ไม่โทร. เป็นค่าเริ่มต้นหรือต้องเพิ่มอะไรอีก?
คำตอบ:
คุณสามารถฉีดActivatedRoute
และสมัครสมาชิกได้params
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
เราเตอร์จะทำลายและสร้างส่วนประกอบใหม่เมื่อนำทางไปยังเส้นทางอื่นเท่านั้น เมื่อมีการอัปเดตพารามิเตอร์เส้นทางหรือพารามิเตอร์แบบสอบถามเท่านั้น แต่เส้นทางเหมือนกันส่วนประกอบจะไม่ถูกทำลายและสร้างขึ้นใหม่
อีกวิธีหนึ่งในการบังคับให้สร้างส่วนประกอบใหม่คือการใช้กลยุทธ์การใช้ซ้ำที่กำหนดเอง ดูเพิ่มเติมเราเตอร์ Angular2 2.0.0 ไม่โหลดคอมโพเนนต์เมื่อ url เดียวกันโหลดด้วยพารามิเตอร์ต่างกัน? (ดูเหมือนจะไม่มีข้อมูลมากนักว่าจะใช้งานอย่างไร)
คุณสามารถปรับ reuseStrategy บนเราเตอร์ได้
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
Coud ไม่ได้พูดถึง Angular เวอร์ชันอื่น ๆ
ฉันใช้สิ่งต่อไปนี้และได้ผล
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
คุณอาจต้องโหลดหน้าใหม่หรือไม่? นี่คือวิธีแก้ปัญหาของฉัน: ฉันได้เปลี่ยน@NgModule (ในไฟล์app-routeing.module.tsในกรณีของฉัน):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
NgOnInit
จะถูกเรียกหนึ่งครั้งเมื่อสร้างอินสแตนซ์ สำหรับอินสแตนซ์เดียวกันNgOnInit
จะไม่ถูกเรียกอีก เพื่อที่จะเรียกได้ว่าจำเป็นต้องทำลายอินสแตนซ์ที่สร้างขึ้น
ในวิธีการนำทางของคุณ
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
ฉันมีปัญหาเดียวกันนอกจากนี้ฉันได้รับคำเตือน:
did you forget to call `ngZone.run()`
ไซต์นี้เป็นทางออกที่ดีที่สุด:
import { Router } from '@angular/router';
import { NgZone } from '@angular/core';
...
constructor(
private ngZone:NgZone,
private _router: Router
){ }
redirect(to) {
// call with ngZone, so that ngOnOnit of component is called
this.ngZone.run(()=>this._router.navigate([to]));
}
ปัญหานี้น่าจะมาจากข้อเท็จจริงที่ว่าคุณไม่ได้ยกเลิกการสมัครสมาชิกโดยใช้ ngOnDestroy นี่คือวิธีที่จะทำให้เสร็จ
นำเข้าการสมัครสมาชิก rxjs ต่อไปนี้
import { Subscription } from 'rxjs/Subscription';
เพิ่ม OnDestory ในการนำเข้า Angular Core ของคุณ
import { Component, OnDestroy, OnInit } from '@angular/core';
เพิ่ม OnDestory ในคลาสส่งออกของคุณ
export class DisplayComponent implements OnInit, OnDestroy {
สร้างคุณสมบัติอ็อบเจ็กต์ที่มีค่า Subscription จาก rxjs ภายใต้คลาสเอ็กซ์พอร์ตของคุณสำหรับการสมัครสมาชิกแต่ละคอมโพเนนต์
myVariable: Subscription;
ตั้งค่าการสมัครของคุณเป็น MyVariable: Subscriptions
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
จากนั้นด้านล่าง ngOninit ให้วางตะขอวงจรชีวิตของ ngOnDestory () และใส่คำสั่งยกเลิกการสมัครของคุณสำหรับการสมัครของคุณ หากคุณมีหลายรายการให้เพิ่มมากขึ้น
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
แทนngOnDestroy
ตัวเองเกินไป ;-)
สร้างเส้นทางอื่นสำหรับส่วนประกอบเดียวกันในอาร์เรย์เส้นทาง
เส้นทาง const: Routes = [{path: "app", component: MyComponent}, {path: "app-reload", component: MyComponent}];
หาก URL ปัจจุบันคือ "app" ให้นำทางโดยใช้ "app-reload" และในทางกลับกัน
นี่คือชุดของแนวคิดที่ดีที่สุดในหน้านี้พร้อมข้อมูลเพิ่มเติม
โซลูชันที่ 1 - ใช้การสมัครสมาชิก params:
บทช่วยสอน: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
เอกสาร: https://angular.io/api/router/ActivatedRoute#params
ในแต่ละองค์ประกอบการกำหนดเส้นทางของคุณที่ใช้ตัวแปรพารามีดังต่อไปนี้:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
// ...
@Component({
// ...
})
export class MyComponent implements OnInit, OnDestroy {
paramsSub: Subscription;
// ...
constructor(activeRoute: ActivatedRoute) {
}
public ngOnInit(): void {
// ...
this.paramsSub = this.activeRoute.params.subscribe(val => {
// Handle param values here
});
// ...
}
// ...
public ngOnDestroy(): void {
// Prevent memory leaks
this.paramsSub.unsubscribe();
}
}
ปัญหาทั่วไปบางประการเกี่ยวกับรหัสนี้คือการสมัครสมาชิกเป็นแบบอะซิงโครนัสและอาจเป็นเรื่องยุ่งยากในการจัดการ นอกจากนี้คุณต้องไม่ลืมยกเลิกการสมัครบน ngOnDestroy ไม่เช่นนั้นสิ่งเลวร้ายอาจเกิดขึ้นได้
สิ่งที่ดีคือนี่เป็นวิธีที่มีเอกสารและใช้กันทั่วไปในการจัดการปัญหานี้ นอกจากนี้ยังมีการปรับปรุงประสิทธิภาพด้วยวิธีนี้เนื่องจากคุณใช้เทมเพลตซ้ำแทนที่จะทำลายและสร้างใหม่ทุกครั้งที่คุณเยี่ยมชมเพจ
โซลูชันที่ 2 - shouldReuseRoute / onSameUrlNavigation:
เอกสาร: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
เอกสาร: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
เอกสาร: https://angular.io/api/router/ActivatedRouteSnapshot#params
ค้นหาตำแหน่งที่RouterModule.forRoot
อยู่ในโครงการของคุณ (โดยปกติจะพบใน app-Routing.module.ts หรือ app.module.ts):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
จากนั้นใน AppComponent ให้เพิ่มสิ่งต่อไปนี้:
import { Component, OnInit} from '@angular/core';
import { Router } from '@angular/router';
// ...
@Component({
// ...
})
export class AppComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit() {
// Allows for ngOnInit to be called on routing to the same routing Component since we will never reuse a route
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
// ...
}
// ...
}
สุดท้ายในส่วนประกอบการกำหนดเส้นทางของคุณตอนนี้คุณสามารถจัดการตัวแปรพาราได้ดังนี้:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
// ...
@Component({
// ...
})
export class MyComponent implements OnInit {
// ...
constructor(activeRoute: ActivatedRoute) {
}
public ngOnInit(): void {
// Handle params
const params = +this.activeRoute.snapshot.params;
// ...
}
// ...
}
ปัญหาทั่วไปในการแก้ปัญหานี้ไม่ใช่เรื่องธรรมดา นอกจากนี้คุณกำลังเปลี่ยนพฤติกรรมเริ่มต้นของเฟรมเวิร์กเชิงมุมดังนั้นคุณสามารถพบปัญหาที่คนทั่วไปไม่เคยพบเจอ
สิ่งที่ดีคือรหัสทั้งหมดของคุณซิงโครนัสและเข้าใจง่ายขึ้น
ลองย้ายโค้ดที่คุณมีใน ngOnInit ไปที่ ngAfterViewInit อย่างหลังดูเหมือนจะถูกเรียกในการนำทางของเราเตอร์และควรช่วยคุณในกรณีนี้
เมื่อคุณต้องการให้เราเตอร์ไปที่หน้าเดียวกันและต้องการเรียกใช้ ngOnInit () คุณจึงทำเช่นนั้นเช่น
this.router.navigate (['หมวดหมู่ / รายการ', หมวดหมู่]). แล้ว (() => window.location.reload ());