Tôi đang gọi router.navigate
trên cùng một trang với một số tham số chuỗi truy vấn. Trong trường hợp này, ngOnInit()
không gọi. Đó là theo mặc định hay tôi cần thêm bất cứ điều gì khác?
Tôi đang gọi router.navigate
trên cùng một trang với một số tham số chuỗi truy vấn. Trong trường hợp này, ngOnInit()
không gọi. Đó là theo mặc định hay tôi cần thêm bất cứ điều gì khác?
Câu trả lời:
Bạn có thể tiêm ActivatedRoute
và đăng kýparams
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
Bộ định tuyến chỉ phá hủy và tạo lại thành phần khi nó điều hướng đến một tuyến đường khác. Khi chỉ các tham số định tuyến hoặc tham số truy vấn được cập nhật nhưng tuyến đường vẫn như cũ, thành phần sẽ không bị hủy và tạo lại.
Một cách khác để buộc tạo lại thành phần là sử dụng chiến lược tái sử dụng tùy chỉnh. Xem thêm Bộ định tuyến Angular2 2.0.0 không tải lại các thành phần khi cùng một url được tải với các thông số khác nhau? (dường như vẫn chưa có nhiều thông tin về cách triển khai)
Bạn có thể điều chỉnh tốc độ sử dụng lại trên Router.
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
vào các đối tượng cấu hình như sau: RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
. Tuy nhiên, Coud không nói cho bất kỳ phiên bản Angular nào khác.
Tôi đã sử dụng những điều sau đây và nó hoạt động.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
Bạn có thể cần tải lại trang không? Đây là giải pháp của tôi: Tôi đã thay đổi @NgModule (trong tệp app-routing.module.ts trong trường hợp của tôi):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
Trên phương pháp điều hướng của bạn,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
Tôi đã gặp vấn đề tương tự, ngoài ra, tôi nhận được cảnh báo:
did you forget to call `ngZone.run()`
Trang web này cung cấp giải pháp tốt nhất:
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]));
}
Vấn đề này có thể xuất phát từ thực tế là bạn không chấm dứt đăng ký của mình bằng ngOnDestroy. Đây là cách để hoàn thành.
Nhập đăng ký rxjs sau.
import { Subscription } from 'rxjs/Subscription';
Thêm OnDestory vào Angular Core Import của bạn.
import { Component, OnDestroy, OnInit } from '@angular/core';
Thêm OnDestory vào lớp xuất của bạn.
export class DisplayComponent implements OnInit, OnDestroy {
Tạo thuộc tính đối tượng với giá trị Đăng ký từ rxjs trong lớp xuất của bạn cho mỗi đăng ký trên thành phần.
myVariable: Subscription;
Đặt giá trị đăng ký của bạn thành MyVariable: Đăng ký.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Sau đó, ngay bên dưới ngOninit đặt móc vòng đời ngOnDestory () và đưa vào tuyên bố hủy đăng ký cho đăng ký của bạn. Nếu bạn có nhiều, hãy thêm nhiều
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
thay vì ngOnDestroy
chính mình ;-)
Đây là bộ sưu tập các ý tưởng hay nhất trên trang này với nhiều thông tin hơn
Giải pháp 1 - Sử dụng đăng ký tham số:
Hướng dẫn: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
Tài liệu: https://angular.io/api/router/ActiisedRoute#params
Trong mỗi thành phần định tuyến của bạn sử dụng các biến tham số bao gồm những điều sau:
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();
}
}
Một số vấn đề phổ biến với mã này là đăng ký không đồng bộ và có thể khó xử lý hơn. Ngoài ra, bạn không thể quên hủy đăng ký trên ngOnDestroy nếu không điều tồi tệ có thể xảy ra.
Điều tốt là đây là cách được ghi chép và phổ biến nhất để xử lý vấn đề này. Cũng có một cải tiến về hiệu suất làm theo cách này vì bạn đang sử dụng lại mẫu thay vì hủy và tạo lại mỗi khi bạn truy cập một trang.
Giải pháp 2 - shouldReuseRoute / onSameUrlNavigation:
Tài liệu: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
Tài liệu: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
Tài liệu: https://angular.io/api/router/ActiisedRouteSnapshot#params
Tìm RouterModule.forRoot
vị trí đặt trong dự án của bạn (thường được tìm thấy trong app-routing.module.ts hoặc app.module.ts):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
Sau đó, trong AppComponent thêm những thứ sau:
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;
};
// ...
}
// ...
}
Cuối cùng, trong các thành phần định tuyến của bạn, bây giờ bạn có thể xử lý các biến tham số như sau:
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;
// ...
}
// ...
}
Các vấn đề phổ biến với giải pháp này là nó không phổ biến. Ngoài ra, bạn đang thay đổi hành vi mặc định của khung công tác Angular, vì vậy bạn có thể gặp phải các vấn đề mà mọi người thường không gặp phải.
Điều tốt là tất cả mã của bạn đều đồng bộ và dễ hiểu hơn.
Cân nhắc việc chuyển mã bạn có trong ngOnInit vào ngAfterViewInit. Cái sau dường như được gọi trên điều hướng bộ định tuyến và sẽ giúp bạn trong trường hợp này.
Khi bạn muốn bộ định tuyến điều hướng trên cùng một trang và muốn gọi ngOnInit (), vì vậy bạn làm như vậy, ví dụ:
this.router.navigate (['category / list', category]) .then (() => window.location.reload ());