Cách tải lại tuyến đường hiện tại với bộ định tuyến 2 góc


141

Tôi đang sử dụng góc 2 với chiến lược băm.

Thành phần được tải với tuyến đường đó:

"departments/:id/employees"

Cho đến nay tốt.

Sau khi tôi thực hiện lưu hàng loạt thành công nhiều hàng trong bảng đã chỉnh sửa, tôi muốn tải lại url tuyến hiện tại qua:

this.router.navigate([`departments/${this.id}/employees`]);

Nhưng không có gì xảy ra, tại sao?


Hãy xem câu trả lời này cho một câu hỏi tương tự: stackoverflow.com/a/44580036/550975
Serj Sagan

Câu trả lời:


46

Nếu điều hướng () của bạn không thay đổi URL đã được hiển thị trên thanh địa chỉ của trình duyệt, bộ định tuyến không có gì để làm. Đây không phải là công việc của bộ định tuyến để làm mới dữ liệu. Nếu bạn muốn làm mới dữ liệu, hãy tạo một dịch vụ được đưa vào thành phần và gọi chức năng tải trên dịch vụ. Nếu dữ liệu mới sẽ được truy xuất, nó sẽ cập nhật chế độ xem thông qua các ràng buộc.


2
Bây giờ bạn nói tôi phải đồng ý NHƯNG ... bộ định tuyến angularjs ui có tùy chọn tải lại, do đó, việc tải lại tuyến đường bị mờ ;-) Nhưng vâng, tôi chỉ có thể tải lại dữ liệu cho mẹo đó thực sự rõ ràng ...
Pascal

83
Tôi không đồng ý nếu bạn muốn chạy lại các vệ sĩ, hãy nói nếu ai đó đăng xuất?
Jackie

1
@Jackie Tôi đã nghĩ rằng có lẽ bạn chỉ có thể chạy lại các vệ sĩ ... nếu họ có các chuyển hướng được tích hợp sẵn, thì điều đó có thể làm nên chuyện.
OldTimeideosGuy

11
@YakovFain xin lỗi, nhưng điều này là sai. Điều này có nghĩa là bây giờ bạn có hai nguồn sự thật cho hành vi tuyến đường - một nguồn xảy ra trong quá trình bảo vệ, nguồn kia xảy ra trong thành phần. Giờ đây, bạn không chỉ có khả năng sao chép logic, mà bạn còn gặp phải luồng dữ liệu tự nhiên hơn: 1. thực hiện thay đổi đối với API, 2. làm mới tuyến đường để tìm nạp trạng thái dữ liệu mới từ API, biến API thành nguồn gốc của sự thật. Đơn giản là không có lý do KHÔNG cung cấp cho người dùng khả năng kích hoạt lại tuyến theo cách thủ công để luồng dữ liệu tự nhiên có thể xảy ra lần nữa.
AgmLauncher

4
Tôi không nghĩ rằng đây là một câu trả lời tốt. Các bộ định tuyến nên là nguồn sự thật cho dữ liệu của bạn. Nếu bạn phải tải lại thông qua một dịch vụ riêng biệt, thì bộ định tuyến không còn biết về phiên bản mới nhất và các thành phần của bạn không còn có thể dựa vào bộ định tuyến của bạn làm nguồn gốc của sự thật.
Dan King

124

Điều này bây giờ có thể được thực hiện trong Angular 5.1 bằng cách sử dụng thuộc onSameUrlNavigationtính của cấu hình Bộ định tuyến.

Tôi đã thêm một blog giải thích làm thế nào ở đây nhưng ý chính của nó là như sau

https://medium.com/engineering-on-the-incline/reloading-civerse-route-on-click-angular-5-1a1bfc740ab2

Trong onSameUrlNavigationtùy chọn cho phép cấu hình bộ định tuyến của bạn , đặt nó thành 'reload'. Điều này khiến Bộ định tuyến kích hoạt chu kỳ sự kiện khi bạn cố điều hướng đến tuyến đường đang hoạt động.

@ngModule({
 imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})],
 exports: [RouterModule],
 })

Trong định nghĩa tuyến đường của bạn, đặt runGuardsAndResolversthành always. Điều này sẽ cho bộ định tuyến luôn khởi động các vệ sĩ và giải quyết các chu kỳ, bắn các sự kiện liên quan.

export const routes: Routes = [
 {
   path: 'invites',
   component: InviteComponent,
   children: [
     {
       path: '',
       loadChildren: './pages/invites/invites.module#InvitesModule',
     },
   ],
   canActivate: [AuthenticationGuard],
   runGuardsAndResolvers: 'always',
 }
]

Cuối cùng, trong mỗi thành phần mà bạn muốn kích hoạt tải lại, bạn cần xử lý các sự kiện. Điều này có thể được thực hiện bằng cách nhập bộ định tuyến, liên kết với các sự kiện và gọi một phương thức khởi tạo để đặt lại trạng thái của thành phần của bạn và tìm nạp lại dữ liệu nếu cần.

export class InviteComponent implements OnInit, OnDestroy {
 navigationSubscription;     

 constructor(
   // … your declarations here
   private router: Router,
 ) {
   // subscribe to the router events. Store the subscription so we can
   // unsubscribe later.
   this.navigationSubscription = this.router.events.subscribe((e: any) => {
     // If it is a NavigationEnd event re-initalise the component
     if (e instanceof NavigationEnd) {
       this.initialiseInvites();
     }
   });
 }

 initialiseInvites() {
   // Set default values and re-fetch any data you need.
 }

 ngOnDestroy() {
   if (this.navigationSubscription) {
     this.navigationSubscription.unsubscribe();
   }
 }
}

Với tất cả các bước này, bạn nên kích hoạt tải lại tuyến đường.


Có cách nào để tải lại thành phần thay vì gọi một initchức năng không,
Ebraheem Alrabeea

Tôi không nghĩ vậy ... trừ khi bạn điều hướng khỏi tuyến đường và quay lại. Một hàm init không phải là kết thúc của thế giới, bạn có thể điều khiển việc khởi tạo đến điểm mà nó có tác dụng tương tự như tải lại thành phần. Có bất kỳ lý do cụ thể mà bạn muốn thực hiện tải lại đầy đủ mà không có init?
Simon McClive

Tôi đã tìm ra một giải pháp cho vấn đề của tôi, Cảm ơn bạn đã phản hồi và blog của nó rất hữu ích.
Ebraheem Alrabeea

Cách thực hiện trong Angular 4 ngoài cửa sổ tải lại.
Vishakha

Hoạt động tuyệt vời cho ứng dụng Angular5 của tôi! Hủy đăng ký trong ngOnDestroy () khá quan trọng - thú vị khi bạn không làm điều đó :-)
BobC

107

Tạo một hàm trong bộ điều khiển chuyển hướng đến tuyến đường dự kiến ​​như vậy

redirectTo(uri:string){
   this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
   this.router.navigate([uri]));
}

sau đó sử dụng nó như thế này

this.redirectTo('//place your uri here');

chức năng này sẽ chuyển hướng đến một tuyến giả và nhanh chóng quay trở lại tuyến đích mà người dùng không nhận ra.


3
Cảm ơn! Giải pháp tốt nhất tại đây.
Alan Smith

Giải pháp này hoạt động tốt, chúng ta có thể sử dụng nó cho đến khi chúng ta có được một cái tốt hơn. Cảm ơn @theo.
Sibeesh Venu

12
nó hoạt động như một bùa mê khi tôi sử dụng '/'thay vì'/DummyComponent'
suhailvs

1
Hoạt động tốt trong Angular 7, không có vấn đề trong lịch sử trình duyệt. Tôi đã chọn sử dụng giải pháp này do được nhắm mục tiêu đến một thành phần cụ thể. Dường như với tôi, việc tải lại cùng một trang nói chung là một trường hợp bất thường, do đó, làm cho toàn bộ ứng dụng tuân theo một mô hình cụ thể có vẻ như quá mức cần thiết. Điều này là nhỏ và dễ thực hiện hơn các giải pháp khác.
JE Carter II

1
Được rồi, nó hoạt động nhưng ... nó sẽ tải lại HomeComponent của bạn (hoặc bất cứ thứ gì bạn có trên tuyến "/"), sẽ đi qua toàn bộ vòng đời của ngOnInit / ngOnDestroy mà không mất gì. Tốt hơn là có một tuyến đường cụ thể với một số thành phần giả và nhẹ hoặc bạn sẽ nhận thấy độ trễ
petronius

77

BIÊN TẬP

Đối với các phiên bản mới hơn của Angular (5.1+), hãy sử dụng câu trả lời được đề xuất bởi @Simon McClive

Câu trả lời cũ

Tôi đã tìm thấy cách giải quyết này trong yêu cầu tính năng GitHub cho Angular:

this._router.routeReuseStrategy.shouldReuseRoute = function(){
    return false;
};

this._router.events.subscribe((evt) => {
    if (evt instanceof NavigationEnd) {
        this._router.navigated = false;
        window.scrollTo(0, 0);
    }
});

Tôi đã thử thêm nó vào chức năng app.component.ts của tôi ngOnInitvà nó chắc chắn đã hoạt động. Tất cả các lần nhấp tiếp theo trên cùng một liên kết bây giờ tải lại componentvà dữ liệu.

Liên kết với yêu cầu tính năng GitHub ban đầu

Tín dụng vào mihaicux2 trên GitHub.

Tôi đã thử nghiệm phiên bản này 4.0.0-rc.3vớiimport { Router, NavigationEnd } from '@angular/router';


1
Chỉ cần thử điều này trong Angular 4.4.x và điều này hoàn toàn hoạt động. Cảm ơn!
Đội ngũ Mindsect

1
Điều này rất tốt cho tôi, cho đến khi tôi triển khai thanh điều hướng của Vật liệu để điều hướng qua các tuyến con của mỗi tuyến phụ huynh trong ứng dụng của mình. Khi người dùng truy cập trang chạy mã này, thanh mực hoạt hình sẽ biến mất. (Tại sao? Tôi không có đủ thời gian hoặc không gian để giải thích ...)
andreisrob 22/12/17

3
Đây là một ý tưởng rất tệ - ActivatedRoute của bạn bây giờ sẽ luôn giống nhau.
artuska

1
@AnandTyagi Hãy thử giải pháp SimonMcClives nếu bạn đang ở Angular 5.1+. Có lẽ điều đó làm việc tốt hơn cho bạn.
Arg0n

2
Ý tưởng rất tệ ... Bởi vì một khi nó áp dụng routeReuseStrargety.shouldReuseRoute = false, thì nó sẽ tải mọi thành phần của hệ thống phân cấp thành phần. Vì vậy, nó có nghĩa là mọi thành phần cha mẹ và con của bạn bắt đầu tải lại trên bất kỳ thay đổi url. Vì vậy, không có ý nghĩa của việc sử dụng khuôn khổ này.
PSabuwala

27

Tiểu xảo: sử dụng cùng một đường dẫn với một số thông số giả. Ví dụ-

refresh(){
  this.router.navigate(["/same/route/path?refresh=1"]);
}

12
Bây giờ: this.router.navigate(['/pocetna'], { queryParams: { 'refresh': 1 } });route.queryParams.subscribe(val => myRefreshMethod())nơi route: ActivatedRouteđược tiêm trong thành phần được làm mới ... Hy vọng nó sẽ giúp
insan-e

4
Hiện tại trong Angular 7, điều này dường như không còn hoạt động nữa. Bất cứ ai có thể xác nhận, hoặc tôi đang làm điều gì sai? (Tôi cũng đã thử biến thể nhẹ của
insan

2
Một chút xấu xí có lẽ.
Dabbbb.

18

Tôi đang sử dụng cái này cho dự án Angular 9:

reloadCurrentRoute() {
    let currentUrl = this.router.url;
    this.router.navigateByUrl('/', {skipLocationChange: true}).then(() => {
        this.router.navigate([currentUrl]);
    });
}

PS: Đã thử nghiệm và cũng hoạt động trên "Angular 7, 8"


Tôi nghĩ rằng tôi rất thích trải nghiệm của mình với giải pháp này. Đối với tôi, nó dường như tải lại toàn bộ thành phần liên quan đến tuyến đường. Trong tình huống của tôi, một bộ định tuyến thông thường với các tham số định tuyến khác nhau sẽ giữ cho thành phần được tải và chỉ tải các thay đổi mới từ ngOnInit (dựa trên các tham số tuyến). Giải pháp của bạn dường như không làm điều này, nó dường như thực sự tải lại toàn bộ thành phần và sau đó thực hiện thay đổi trong ngOnInit dựa trên thông số tuyến. Nhưng dù sao, đó là một bất tiện nhỏ cho tôi trong tình huống của tôi và giải pháp của bạn phù hợp với nhu cầu của tôi.
Evan Sevy

17

Angular 2-4 tuyến tải lại hack

Đối với tôi, sử dụng phương thức này bên trong một thành phần gốc (thành phần, có mặt trên bất kỳ tuyến đường nào) hoạt động:

onRefresh() {
  this.router.routeReuseStrategy.shouldReuseRoute = function(){return false;};

  let currentUrl = this.router.url + '?';

  this.router.navigateByUrl(currentUrl)
    .then(() => {
      this.router.navigated = false;
      this.router.navigate([this.router.url]);
    });
  }

Hãy cẩn thận với phương pháp này, điều này sẽ ảnh hưởng đến toàn cầu hành vi của bộ định tuyến (tuyến cha mẹ sẽ luôn tải lại khi điều hướng giữa các tuyến con).
seidme

16

Điều này làm việc cho tôi như một nét duyên dáng

this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate([<route>]));

3
Đây là câu trả lời đơn giản nhất. Tôi sẽ đánh dấu đây là câu trả lời được chấp nhận nếu tôi có thể. Trái với câu trả lời được chấp nhận, có thể có những tình huống bạn cần tải lại từng thành phần được sử dụng trên một trang và phải tải lại từng trang một, có thể ở các tuyến khác nhau, sẽ bị quá tải ngay cả thông qua dịch vụ.
Andrew Junior Howard

8

Trên trang tải lại thay đổi param sẽ không xảy ra. Đây thực sự là tính năng tốt. Không cần tải lại trang nhưng chúng ta nên thay đổi giá trị của thành phần. Phương thức paramChange sẽ gọi thay đổi url. Vì vậy, chúng tôi có thể cập nhật dữ liệu thành phần

/product/: id / details

import { ActivatedRoute, Params, Router } from ‘@angular/router’;

export class ProductDetailsComponent implements OnInit {

constructor(private route: ActivatedRoute, private router: Router) {
    this.route.params.subscribe(params => {
        this.paramsChange(params.id);
    });
}

// Call this method on page change

ngOnInit() {

}

// Call this method on change of the param
paramsChange(id) {

}

7

Đây là những gì tôi đã làm với Angular 9 . Tôi không chắc chắn điều này hoạt động trong các phiên bản cũ hơn.

Bạn sẽ cần gọi nó khi bạn cần tải lại.

 this.router.navigate([], {
    skipLocationChange: true,
    queryParamsHandling: 'merge' //== if you need to keep queryParams
  })

Bộ định tuyến forRoot cần phải có SameUrlNavulation được đặt thành 'tải lại'

 RouterModule.forRoot(appRoutes, {
  // ..
  onSameUrlNavigation: 'reload',
  // ..
})

Và mọi tuyến đường của bạn cần phải có runGuardsAndResolvers được đặt thành 'luôn luôn'

{
    path: '',
    data: {},
    runGuardsAndResolvers: 'always'
},

1
Đây là câu trả lời chính xác. "onSameUrlNavulation" hoạt động kể từ Angular 5. Vui lòng nâng cấp để di chuyển nó lên hàng đầu
Yaroslav Yakovlev

Điều này đã không làm việc cho tôi. Andris dưới đây đã làm. Mặc dù tải lại của Andris không 'sạch' như một điều hướng tuyến thông thường thực sự. Nó dường như không tải lại toàn bộ trang, nhưng dường như nó tải lại toàn bộ thành phần được liên kết với tuyến đường. Tôi chỉ cần các thành phần con để tải lại dựa trên các tham số tuyến đường, không phải toàn bộ thành phần được liên kết với tuyến đường. Nhưng dù sao, nó hoạt động đủ tốt. Chỉ cần nghĩ rằng tôi sẽ đồng ý với kinh nghiệm của tôi.
Evan Sevy

4

Đối với tôi làm việc mã hóa với

this.router.routeReuseStrategy.shouldReuseRoute = function() {
    return false;
    // or
    return true;
};

1
Không được khuyến khích! Mọi người tiếp tục đăng lại giải pháp này theo những cách khác nhau trong suốt SO này. Có, nó có thể khắc phục sự cố ngay lập tức của bạn nhưng sau đó bạn sẽ quên rằng bạn đã thực hiện việc này và bạn sẽ mất hàng giờ để tìm hiểu lý do tại sao ứng dụng của bạn gặp phải hành vi kỳ lạ.
Helzgate

Nếu bạn phải sử dụng giải pháp này, hãy sử dụng giải pháp Ebraheem Alrabee 'và chỉ áp dụng nó cho một tuyến đường duy nhất.
Helzgate

4

Theo như tôi biết thì điều này không thể thực hiện được với bộ định tuyến trong Angular 2. Nhưng bạn chỉ có thể làm:

window.location.href = window.location.href

Để tải lại xem.


3
Điều này làm mới toàn bộ ứng dụng không chỉ là tuyến đường hiện tại!
rostamiani

@HelloWorld - Nơi để đặt logic như vậy trong góc 7?
Pra_A

Không quan trọng phiên bản góc nào - đây chỉ là mã js thông thường
HelloWorld

Đặt cái này vào chức năng click. window.location.href = '/' hoặc '/ login' mà everis định nghĩa bên trong app-định tuyến.module.ts. Trong trường hợp của tôi khi người dùng đăng xuất, nó sẽ quay trở lại màn hình đăng nhập để khi đăng xuất tôi xóa tất cả dữ liệu auths và khi thành công, hãy sử dụng window.location.href = '/'. Điều này có nghĩa là tải lại trang loagin và chạy lại tất cả javascript. Đối với thay đổi tuyến đường bình thường, tôi sẽ không đề xuất điều này khi không yêu cầu chạy lại các chức năng.
Ali Exalter

Tôi tin rằng điều này có thể thiết lập lại hoàn toàn cửa hàng NgRx của bạn - vì vậy mọi dữ liệu bạn đã tìm nạp sẽ bị mất.
John Q

3

Tìm thấy một giải pháp nhanh chóng và đơn giản mà không cần phải sửa lại các hoạt động bên trong của góc:

Về cơ bản: Chỉ cần tạo một tuyến đường thay thế với cùng một mô-đun đích và chỉ cần chuyển đổi giữa chúng:

const routes: Routes = [
  {
    path: 'gesuch',
    loadChildren: './sections/gesuch/gesuch.module#GesuchModule'
  },
  {
    path: 'gesuch-neu',
    loadChildren: './sections/gesuch/gesuch.module#GesuchModule'
  }
];

Và đây là menu toggeling:

<ul class="navigation">
    <li routerLink="/gesuch-neu" *ngIf="'gesuch' === getSection()">Gesuch</li>
    <li routerLink="/gesuch" *ngIf="'gesuch' !== getSection()">Gesuch</li>
</ul>

Hy vọng nó giúp :)


Điều gì xảy ra nếu tuyến đường thay thế có tham số và bạn muốn tải lại khi tham số thay đổi?
Mukus

3

Một chút khó khăn nhưng

this.router.onSameUrlNavigation = 'reload';
this.router.navigateByUrl(this.router.url).then(() => {

    this.router.onSameUrlNavigation = 'ignore';

});

2

Trong trường hợp của tôi:

const navigationExtras: NavigationExtras = {
    queryParams: { 'param': val }
};

this.router.navigate([], navigationExtras);

làm việc đúng


2

triển khai OnInit và gọi ngOnInit () trong phương thức cho route.navigate ()

Xem một ví dụ:

export class Component implements OnInit {

  constructor() {   }

  refresh() {
    this.router.navigate(['same-route-here']);
    this.ngOnInit();   }

  ngOnInit () {

  }

2

Đã giải quyết một kịch bản tương tự bằng cách sử dụng một thành phần giả và tuyến đường cho reload, mà thực sự là một redirect. Điều này chắc chắn không bao gồm tất cả các kịch bản người dùng nhưng chỉ hoạt động cho kịch bản của tôi.

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Http } from '@angular/http';

@Component({
  selector: 'reload',
  template: `
    <h1>Reloading...</h1>
  `,
})
export class ReloadComponent implements OnInit{
  constructor(private router: Router, private route: ActivatedRoute) {
  }

  ngOnInit() {
    const url = this.route.snapshot.pathFromRoot.pop().url.map(u => u.path).join('/');
    this.router.navigateByUrl(url);
  }
}

Định tuyến có dây để bắt tất cả các url bằng cách sử dụng ký tự đại diện:

import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { LoginViewComponent } from './views/login/login.component';
import { HomeViewComponent } from './views/home/home.component';
import { ReloadComponent } from './views/reload/reload.component';

@NgModule({
  declarations: [ 
    LoginViewComponent, HomeViewComponent, ReloadComponent
  ],
  imports: [
    RouterModule.forRoot([
      { path: 'login', component: LoginViewComponent },
      { path: 'home', component: HomeViewComponent },
      { 
        path: 'reload',
        children: [{
          path: '**',
          component: ReloadComponent 
        }]
      },
      { path: '**', redirectTo: 'login'}
    ])
  ],
  exports: [
    RouterModule,
  ],
  providers: [],

})
export class AppRoutingModule {}

Để sử dụng điều này, chúng ta chỉ cần thêm tải lại vào url nơi chúng ta muốn đi:

  this.router.navigateByUrl('reload/some/route/again/fresh', {skipLocationChange: true})

2

Có nhiều cách tiếp cận khác nhau để làm mới lộ trình hiện tại

Thay đổi hành vi của bộ định tuyến (Kể từ góc 5.1) Đặt bộ định tuyến trênSameUrlNavulation thành 'tải lại'. Điều này sẽ phát ra các sự kiện bộ định tuyến trên cùng một Điều hướng URL.

  • Sau đó, bạn có thể xử lý chúng bằng cách đăng ký một tuyến đường
  • Bạn có thể sử dụng nó với sự kết hợp của runGuardsAndResolvers để chạy lại trình phân giải

Để bộ định tuyến không bị ảnh hưởng

  • Vượt qua một truy vấn làm mớiParam với dấu thời gian hiện tại trong URL và đăng ký queryParams trong thành phần định tuyến của bạn.
  • Sử dụng sự kiện kích hoạt của ổ cắm bộ định tuyến để giữ thành phần được định tuyến.

Tôi đã viết một lời giải thích chi tiết hơn theo https://medium.com/@kevinkreuzer/refresh-civerse-route-in-angular-512a19d58f6e

Hi vọng điêu nay co ich.


1

Giả sử rằng tuyến đường của thành phần bạn muốn làm mới là view, sau đó sử dụng:

this.router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
  if (future.url.toString() === 'view' && curr.url.toString() === future.url.toString()) {
    return false;
  }
  return (future.routeConfig === curr.routeConfig);
}; 

bạn có thể thêm một debugger phương thức bên trong để biết tuyến đường chính xác sẽ đến sau khi điều hướng đến "departments/:id/employees".


1

Một giải pháp là truyền tham số giả (tức là thời gian tính bằng giây), theo cách này, liên kết luôn được tải lại:

this.router.navigate(["/url", {myRealData: RealData, dummyData: (new Date).getTime()}])

1

Tôi đang sử dụng setTimeoutnavigationByUrl để giải quyết vấn đề này ... Và nó đang hoạt động tốt với tôi.

Nó được chuyển hướng đến URL khác và thay vào đó lại xuất hiện trong URL hiện tại ...

 setTimeout(() => {
     this.router.navigateByUrl('/dashboard', {skipLocationChange: false}).then(() =>
           this.router.navigate([route]));
     }, 500)

1

Tôi tin rằng điều này đã được giải quyết (nguyên bản) trong Angular 6+; kiểm tra

Nhưng điều này hoạt động cho toàn bộ tuyến đường (bao gồm tất cả các tuyến trẻ em)

Nếu bạn muốn nhắm mục tiêu một thành phần duy nhất, đây là cách: Sử dụng tham số truy vấn thay đổi, để bạn có thể điều hướng bao nhiêu lần tùy ý.

Tại điểm điều hướng (lớp)

   this.router.navigate(['/route'], {
        queryParams: { 'refresh': Date.now() }
    });

Trong Thành phần mà bạn muốn "làm mới / tải lại"

// . . . Component Class Body

  $_route$: Subscription;
  constructor (private _route: ActivatedRoute) {}

  ngOnInit() {
    this.$_route$ = this._route.queryParams.subscribe(params => {
      if (params['refresh']) {
         // Do Something
         // Could be calling this.ngOnInit() PS: I Strongly advise against this
      }

    });
  }

  ngOnDestroy() {
    // Always unsubscribe to prevent memory leak and unexpected behavior
    this.$_route$.unsubscribe();
  }

// . . . End of Component Class Body

1

Rất bực bội vì Angular dường như vẫn chưa bao gồm một giải pháp tốt cho việc này. Tôi đã đưa ra một vấn đề github ở đây: https://github.com/angular/angular/issues/31843

Trong khi đó, đây là cách giải quyết của tôi. Nó dựa trên một số giải pháp khác được đề xuất ở trên, nhưng tôi nghĩ nó mạnh hơn một chút. Nó liên quan đến việc đóng gói dịch vụ Bộ định tuyến trong " ReloadRouter", đảm nhiệm chức năng tải lại và cũng thêm RELOAD_PLACEHOLDERcấu hình bộ định tuyến lõi. Điều này được sử dụng để điều hướng tạm thời và tránh kích hoạt bất kỳ tuyến đường khác (hoặc bảo vệ).

Lưu ý: Chỉ sử dụng ReloadRoutertrong những trường hợp đó khi bạn muốn chức năng tải lại. Sử dụng bình thường Routerkhác.

import { Injectable } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class ReloadRouter {
  constructor(public readonly router: Router) {
    router.config.unshift({ path: 'RELOAD_PLACEHOLDER' });
  }

  public navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
    return this.router
      .navigateByUrl('/RELOAD_PLACEHOLDER', {skipLocationChange: true})
      .then(() => this.router.navigate(commands, extras));
  }
}

1

Nhập RouterActivatedRoutetừ@angular/router

import { ActivatedRoute, Router } from '@angular/router';

Tiêm RouterActivatedRoute(trong trường hợp bạn cần bất cứ thứ gì từ URL)

constructor(
    private router: Router,
    private route: ActivatedRoute,
) {}

Nhận bất kỳ tham số nếu cần từ URL.

const appointmentId = this.route.snapshot.paramMap.get('appointmentIdentifier');

Sử dụng một mẹo bằng cách điều hướng đến một hình nộm hoặc url chính sau đó đến url thực tế sẽ làm mới thành phần.

this.router.navigateByUrl('/appointments', { skipLocationChange: true }).then(() => {
    this.router.navigate([`appointment/${appointmentId}`])
});

Trong trường hợp của bạn

const id= this.route.snapshot.paramMap.get('id');
this.router.navigateByUrl('/departments', { skipLocationChange: true }).then(() => {
    this.router.navigate([`departments/${id}/employees`]);
});

Nếu bạn sử dụng tuyến giả thì bạn sẽ thấy một tiêu đề nhấp nháy 'Không tìm thấy' nếu bạn đã triển khai một url không tìm thấy trong trường hợp không khớp với bất kỳ url nào.


0

đăng ký thay đổi tham số tuyến

    // parent param listener ie: "/:id"
    this.route.params.subscribe(params => {
        // do something on parent param change
        let parent_id = params['id']; // set slug
    });

    // child param listener ie: "/:id/:id"
    this.route.firstChild.params.subscribe(params => {
        // do something on child param change
        let child_id = params['id'];
    });

0

Nếu bạn đang thay đổi tuyến đường qua Router Link Thực hiện theo điều này:

  constructor(public routerNavigate: Router){

         this.router.routeReuseStrategy.shouldReuseRoute = function () {
            return false;
          };

          this.router.events.subscribe((evt) => {

            if (evt instanceof NavigationEnd) {

                this.router.navigated = false;
             }
          })
      }

0

Bạn nên sử dụng thuộc tính "onSameUrlNavulation" trong RouterModule và sau đó đăng ký các sự kiện Tuyến https://blog.angularindepth.com/refresh-civerse-route-in-angular-512a19d58f6e


Liên kết đến một giải pháp được hoan nghênh, nhưng vui lòng đảm bảo câu trả lời của bạn hữu ích mà không cần đến nó: thêm ngữ cảnh xung quanh liên kết để người dùng của bạn sẽ có ý tưởng về nó là gì và tại sao lại có, sau đó trích dẫn phần có liên quan nhất của trang bạn ' liên kết lại trong trường hợp trang đích không có sẵn. Câu trả lời ít hơn một liên kết có thể bị xóa.
Alessio

0

Quyết định khi tuyến nên được lưu trữ trả về false

this.router.routeReuseStrategy.shouldReuseRoute = function () {
    return false;
};

và đặt giá trị điều hướng của bộ định tuyến thành false, điều đó cho thấy rằng tuyến đường này không bao giờ định tuyến

this.mySubscription = this.router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
        this.router.navigated = false;
    }
});

0

Tôi đã thử một vài sửa chữa và không có cái nào hoạt động. Phiên bản của tôi rất đơn giản: thêm một tham số chưa sử dụng mới vào các tham số truy vấn

            if (force) {
                let key = 'time';

                while (key in filter) {
                    key = '_' + key;
                }

                filter[key] = Date.now();
            }

            this.router.navigate(['.', { filter: JSON.stringify(filter) }]);

0

window.location.replace

// sử dụng backtick để bao quanh tuyến đường

window.location.replace ( departments/${this.id}/employees)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.