วิธีโหลดเส้นทางปัจจุบันใหม่ด้วยเราเตอร์เชิงมุม 2


156

ฉันใช้ angular 2 กับกลยุทธ์ hashlocation

ส่วนประกอบถูกโหลดด้วยเส้นทางนั้น:

"departments/:id/employees"

ดีมาก

หลังจากที่ฉันทำการบันทึกเป็นกลุ่มสำเร็จของแถวตารางที่แก้ไขหลายแถวฉันต้องการโหลด url เส้นทางปัจจุบันซ้ำผ่าน:

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

แต่ไม่มีอะไรเกิดขึ้นทำไม?


ลองดูคำตอบสำหรับคำถามที่คล้ายกันนี้: stackoverflow.com/a/44580036/550975
Serj Sagan

tech-blog.maddyzone.com/angularjs/javascript/… มีประโยชน์มาก
Rituraj Ratan

คำตอบ:


52

หาก nav ของคุณ () ไม่เปลี่ยน URL ที่แสดงอยู่แล้วบนแถบที่อยู่ของเบราว์เซอร์ของคุณเราเตอร์ก็ไม่ต้องทำอะไร ไม่ใช่หน้าที่ของเราเตอร์ในการรีเฟรชข้อมูล หากคุณต้องการรีเฟรชข้อมูลให้สร้างเซอร์วิสที่แทรกเข้าไปในคอมโพเนนต์และเรียกใช้ฟังก์ชันโหลดบนเซอร์วิส หากจะดึงข้อมูลใหม่ข้อมูลจะอัปเดตมุมมองผ่านการเชื่อมโยง


2
ตอนนี้คุณบอกว่าฉันต้องเห็นด้วย แต่ ... เราเตอร์ angularjs ui มีตัวเลือกการโหลดดังนั้นการโหลดเส้นทางใหม่จึงถูก opiniated ;-) แต่ใช่ฉันสามารถโหลดข้อมูลซ้ำได้สำหรับเคล็ดลับนั้นซึ่งเห็นได้ชัดจริงๆ ...
Pascal

91
ฉันไม่เห็นด้วยว่าถ้าคุณต้องการเรียกใช้ผู้คุมอีกครั้งพูดว่ามีใครออกจากระบบ?
Jackie

1
@ แจ็คกี้ฉันคิดว่าบางทีคุณอาจจะเรียกใช้ยามอีกครั้ง ... ถ้าพวกเขามีการเปลี่ยนเส้นทางในตัวนั่นอาจเป็นเคล็ดลับ
OldTimeGuitarGuy

12
@YakovFain ขอโทษ แต่นี่เป็นเท็จ ซึ่งหมายความว่าตอนนี้คุณมีแหล่งความจริงสองแหล่งสำหรับพฤติกรรมเส้นทาง - แหล่งหนึ่งเกิดขึ้นระหว่างการป้องกันและอีกแหล่งเกิดขึ้นในองค์ประกอบ ไม่เพียง แต่ตอนนี้คุณมีตรรกะที่ซ้ำกัน แต่คุณกำลังขัดขวางการไหลของข้อมูลที่เป็นธรรมชาติมากขึ้น: 1. ทำการเปลี่ยนแปลง API 2. รีเฟรชเส้นทางเพื่อดึงข้อมูลสถานะใหม่จาก API ทำให้ API เป็นแหล่งที่มาของความจริง ไม่มีเหตุผลที่จะไม่ให้ผู้ใช้สามารถเรียกใช้เส้นทางอีกครั้งด้วยตนเองเพื่อให้การไหลของข้อมูลตามธรรมชาติเกิดขึ้นอีกครั้ง
AgmLauncher

4
ฉันไม่คิดว่านี่เป็นคำตอบที่ดี เราเตอร์ควรเป็นแหล่งที่มาของความจริงสำหรับข้อมูลของคุณ หากคุณต้องโหลดซ้ำผ่านบริการแยกเราเตอร์จะไม่ทราบเกี่ยวกับเวอร์ชันล่าสุดอีกต่อไปและส่วนประกอบของคุณจะไม่สามารถพึ่งพาเราเตอร์ของคุณเป็นแหล่งที่มาของความจริงได้อีกต่อไป
Dan King

139

ตอนนี้สามารถทำได้ใน Angular 5.1 โดยใช้onSameUrlNavigationคุณสมบัติของการกำหนดค่าเราเตอร์

ฉันได้เพิ่มบล็อกที่อธิบายถึงวิธีการที่นี่ แต่ส่วนสำคัญของมันมีดังนี้

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

ในการตั้งค่าเราเตอร์ของคุณเปิดใช้งานตัวเลือกการตั้งค่าให้onSameUrlNavigation 'reload'สิ่งนี้ทำให้เราเตอร์เริ่มวงจรเหตุการณ์เมื่อคุณพยายามนำทางไปยังเส้นทางที่ใช้งานอยู่แล้ว

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

ในคำจำกัดความเส้นทางของคุณตั้งค่าการrunGuardsAndResolvers alwaysสิ่งนี้จะบอกให้เราเตอร์เริ่มการทำงานของยามและวงจรรีโซลเวอร์เสมอโดยจะเริ่มต้นเหตุการณ์ที่เกี่ยวข้อง

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

สุดท้ายในแต่ละองค์ประกอบที่คุณต้องการเปิดใช้งานการโหลดซ้ำคุณจะต้องจัดการกับเหตุการณ์นั้น ๆ ซึ่งสามารถทำได้โดยการนำเข้าเราเตอร์เชื่อมโยงกับเหตุการณ์และเรียกใช้วิธีการเริ่มต้นที่รีเซ็ตสถานะของส่วนประกอบของคุณและดึงข้อมูลใหม่หากจำเป็น

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();
   }
 }
}

เมื่อทำตามขั้นตอนเหล่านี้แล้วคุณควรเปิดใช้งานการโหลดเส้นทางใหม่


1
มีวิธีโหลดคอมโพเนนต์แทนการเรียกใช้initฟังก์ชันหรือไม่
Ebraheem Alrabeea

ฉันไม่คิดอย่างนั้น ... เว้นแต่คุณจะออกจากเส้นทางแล้วย้อนกลับมาอีกครั้ง ฟังก์ชัน init ไม่ใช่จุดจบของโลกคุณสามารถควบคุมการเริ่มต้นจนถึงจุดที่มีผลเช่นเดียวกับการโหลดส่วนประกอบซ้ำ มีเหตุผลใดเป็นพิเศษที่คุณต้องการทำการโหลดซ้ำโดยไม่ใช้init?
Simon McClive

ฉันได้หาวิธีแก้ปัญหาของฉันแล้วขอบคุณสำหรับคำตอบและบล็อกนี้มีประโยชน์
Ebraheem Alrabeea

วิธีการทำใน Angular 4 นอกเหนือจากการโหลดหน้าต่าง
วิสาขะ

ใช้งานได้ดีสำหรับแอพ Angular5 ของฉัน! การยกเลิกการสมัครใน ngOnDestroy () เป็นเรื่องสำคัญ - น่าสนใจเมื่อคุณไม่ทำ :-)
BobC

135

สร้างฟังก์ชันในตัวควบคุมที่เปลี่ยนเส้นทางไปยังเส้นทางที่คาดไว้เช่นนั้น

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

แล้วใช้แบบนี้

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

ฟังก์ชันนี้จะเปลี่ยนเส้นทางไปยังเส้นทางจำลองและกลับไปยังเส้นทางปลายทางอย่างรวดเร็วโดยที่ผู้ใช้ไม่รู้ตัว


4
ขอบคุณ! ทางออกที่ดีที่สุดที่นี่
Alan Smith

วิธีนี้ใช้ได้ผลดีเราสามารถใช้สิ่งนี้จนกว่าเราจะได้สิ่งที่ดีกว่า ขอบคุณ @theo.
Sibeesh Venu

13
มันใช้งานได้เหมือนมีเสน่ห์เมื่อฉันใช้'/'แทน'/DummyComponent'
suhailvs

2
ทำงานได้ดีใน Angular 7 โดยไม่มีปัญหาในประวัติเบราว์เซอร์ ฉันเลือกที่จะใช้โซลูชันนี้เนื่องจากถูกกำหนดเป้าหมายไปที่ส่วนประกอบเฉพาะ สำหรับฉันแล้วดูเหมือนว่าการโหลดหน้าเดิมซ้ำนั้นมักจะเป็นกรณีที่ผิดปกติดังนั้นการทำให้แอปพลิเคชันทั้งหมดเป็นไปตามกระบวนทัศน์ที่เฉพาะเจาะจงดูเหมือนว่าจะมากเกินไป ซึ่งมีขนาดเล็กและใช้งานง่ายกว่าโซลูชันอื่น ๆ
JE Carter II

3
โอเคมันใช้งานได้ แต่ ... มันจะโหลด HomeComponent ของคุณซ้ำ (หรืออะไรก็ตามที่คุณมีบนเส้นทาง "/") จะผ่านวงจรการใช้งานทั้งหมดของ ngOnInit / ngOnDestroy โดยไม่มีค่าใช้จ่ายใด ๆ ดีกว่าที่จะมีเส้นทางที่เฉพาะเจาะจงพร้อมส่วนประกอบจำลองและน้ำหนักเบาหรือคุณจะสังเกตเห็นความล่าช้า
petronius

77

แก้ไข

สำหรับ Angular เวอร์ชันใหม่กว่า (5.1+) ให้ใช้คำตอบที่แนะนำโดย @Simon McClive

คำตอบเก่า

ฉันพบวิธีแก้ปัญหานี้ในคำขอคุณสมบัติ GitHub สำหรับ 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);
    }
});

ฉันลองเพิ่มสิ่งนี้ในฟังก์ชั่นapp.component.ts ของฉันngOnInitและมันใช้งานได้จริง การคลิกเพิ่มเติมทั้งหมดในลิงก์เดียวกันจะโหลดcomponentและข้อมูลซ้ำ

ลิงก์ไปยังคำขอคุณลักษณะ GitHub ดั้งเดิม

เครดิตไปที่mihaicux2บน GitHub

ผมทดสอบนี้กับรุ่น4.0.0-rc.3ที่มีimport { Router, NavigationEnd } from '@angular/router';


1
เพิ่งลองสิ่งนี้ใน Angular 4.4.x และใช้งานได้อย่างสมบูรณ์ ขอบคุณ!
Mindsect Team

1
สิ่งนี้ใช้ได้ผลดีสำหรับฉันจนกระทั่งฉันติดตั้งแถบนำทางของ Material เพื่อนำทางผ่านเส้นทางลูกของเส้นทางหลักแต่ละเส้นทางในแอปของฉัน เมื่อผู้ใช้ไปที่หน้าที่เรียกใช้โค้ดนี้แถบหมึกแบบเคลื่อนไหวจะหายไป (ทำไมฉันไม่มีเวลาหรือพื้นที่พอจะอธิบาย ... )
andreisrob

3
นี่เป็นความคิดที่แย่มาก - ตอนนี้ ActivatedRoute ของคุณจะเหมือนเดิมเสมอ
artuska

1
@AnandTyagi ลองใช้โซลูชัน SimonMcClives หากคุณใช้ Angular 5.1+ อาจจะดีกว่าสำหรับคุณ
Arg0n

2
เป็นความคิดที่แย่มาก ... เนื่องจากเมื่อใช้ routeReuseStrategy.shouldReuseRoute = false แล้วมันจะโหลดทุกองค์ประกอบของลำดับชั้นของส่วนประกอบ ดังนั้นจึงหมายความว่าทุกองค์ประกอบหลักและลูกของคุณจะเริ่มโหลดซ้ำเมื่อมีการเปลี่ยนแปลง URL ใด ๆ ดังนั้นจึงไม่มีความหมายของการใช้กรอบนี้
PSabuwala

28

ยุ่งยากเล็กน้อย: ใช้เส้นทางเดียวกันกับพารามิเตอร์จำลอง ตัวอย่างเช่น-

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

12
ตอนนี้: this.router.navigate(['/pocetna'], { queryParams: { 'refresh': 1 } });และroute.queryParams.subscribe(val => myRefreshMethod())ที่ไหนที่route: ActivatedRouteฉีดในส่วนประกอบที่สดชื่น ... หวังว่าจะช่วยได้นะ
insan-e

5
ปัจจุบันใน Angular 7 ดูเหมือนจะไม่ทำงานอีกต่อไป มีใครยืนยันได้หรือว่าฉันทำอะไรผิด? (ฉันลองรูปแบบเล็กน้อยของ insan-e ด้วย)
pbarranis

3
อาจจะน่าเกลียดเล็กน้อย
ตะลุยโจทย์.

23

ฉันใช้อันนี้สำหรับโครงการ Angular 10:

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

PS: ทดสอบแล้วและใช้งานได้กับ "Angular 7, 8, 9"


ฉันคิดว่าฉันจะได้สัมผัสกับประสบการณ์ของฉันกับโซลูชันนี้ สำหรับฉันดูเหมือนว่าจะโหลดส่วนประกอบทั้งหมดที่เกี่ยวข้องกับเส้นทางอีกครั้ง ในสถานการณ์ของฉันเราเตอร์ปกตินำทางด้วยพารามิเตอร์การกำหนดเส้นทางที่แตกต่างกันจะทำให้ส่วนประกอบโหลดและเพียงแค่โหลดการเปลี่ยนแปลงใหม่จาก ngOnInit (ขึ้นอยู่กับพารามิเตอร์เส้นทาง) โซลูชันของคุณดูเหมือนจะไม่ทำเช่นนี้ดูเหมือนว่าจะโหลดส่วนประกอบทั้งหมดซ้ำแล้วจึงทำการเปลี่ยนแปลงใน ngOnInit ตามพารามิเตอร์เส้นทาง อย่างไรก็ตามมันเป็นความไม่สะดวกเล็กน้อยสำหรับฉันในสถานการณ์ของฉันและวิธีแก้ปัญหาของคุณได้ผลตามความต้องการของฉัน
Evan Sevy

20

สิ่งนี้ใช้ได้กับฉันเหมือนมีเสน่ห์

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

3
นี่คือคำตอบที่ง่ายที่สุด ฉันจะทำเครื่องหมายว่านี่เป็นคำตอบที่ยอมรับได้หากทำได้ ตรงกันข้ามกับคำตอบที่ได้รับการยอมรับอาจมีสถานการณ์ที่คุณต้องโหลดซ้ำทุกองค์ประกอบที่ใช้บนหน้าเว็บและต้องโหลดซ้ำทีละรายการซึ่งอาจอยู่คนละเส้นทางก็จะมากเกินไปแม้กระทั่งผ่านบริการ
Andrew Junior Howard

17

แฮ็คโหลดซ้ำเส้นทาง 2-4 เส้นทาง

สำหรับฉันการใช้วิธีนี้ภายในองค์ประกอบรูท (ส่วนประกอบซึ่งมีอยู่ในทุกเส้นทาง) ใช้ได้ผล:

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]);
    });
  }

โปรดใช้ความระมัดระวังด้วยวิธีนี้สิ่งนี้จะส่งผลต่อพฤติกรรมของเราเตอร์ทั่วโลก (เส้นทางหลักจะโหลดซ้ำเสมอเมื่อนำทางระหว่างเส้นทางลูก)
seidme

12

นี่คือสิ่งที่ผมกับเชิงมุม 9 ฉันไม่แน่ใจว่าจะใช้ได้กับเวอร์ชันเก่าหรือไม่

คุณจะต้องเรียกสิ่งนี้เมื่อคุณต้องการโหลดซ้ำ

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

เราเตอร์ forRoot จำเป็นต้องมี SameUrlNavigation ตั้งค่าเป็น 'โหลดซ้ำ'

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

และทุกเส้นทางของคุณจำเป็นต้องมี runGuardsAndResolvers ตั้งค่าเป็น 'always'

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

1
นี่คือคำตอบที่ถูกต้อง "onSameUrlNavigation" ทำงานตั้งแต่ Angular 5 โปรดโหวตให้ย้ายไปด้านบน
Yaroslav Yakovlev

สิ่งนี้ไม่ได้ผลสำหรับฉัน ด้านล่างของ Andris ทำ แม้ว่าการโหลดซ้ำของ Andris จะไม่ 'สะอาด' เท่ากับการนำทางตามเส้นทางปกติจริงๆ ดูเหมือนจะไม่โหลดซ้ำทั้งหน้า แต่ดูเหมือนว่าจะโหลดส่วนประกอบทั้งหมดที่เกี่ยวข้องกับเส้นทางอีกครั้ง ฉันแค่ต้องการส่วนประกอบย่อยเพื่อโหลดซ้ำตามพารามิเตอร์เส้นทางไม่ใช่ส่วนประกอบทั้งหมดที่เกี่ยวข้องกับเส้นทาง อย่างไรก็ตามมันทำงานได้ดีพอ แค่คิดว่าฉันจะพูดถึงประสบการณ์ของฉัน
Evan Sevy

1
ปัญหาของฉันได้รับการแก้ไขโดยบิตสุดท้ายของรหัส การตั้งค่า runGuardsAndResolvers: 'always' บังคับให้แอปใช้ตัวป้องกันดังนั้นการโทรซ้ำไปยัง API ที่มีอยู่ที่นั่น ขอบคุณที่ @Wlada
Travel and code enthousiast

8

ในหน้าโหลดการเปลี่ยนแปลงพารามิเตอร์จะไม่เกิดขึ้น นี่เป็นคุณสมบัติที่ดีจริงๆ ไม่จำเป็นต้องโหลดหน้านี้ซ้ำ แต่เราควรเปลี่ยนค่าของส่วนประกอบ วิธี paramChange จะเรียกการเปลี่ยนแปลง url ดังนั้นเราจึงสามารถอัปเดตข้อมูลส่วนประกอบ

/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) {

}

4

เท่าที่ฉันรู้ว่าไม่สามารถทำได้กับเราเตอร์ใน Angular 2 แต่คุณสามารถทำได้:

window.location.href = window.location.href

เพื่อโหลดมุมมองซ้ำ


3
นี่เป็นการรีเฟรชแอปพลิเคชันทั้งหมดไม่ใช่แค่เส้นทางปัจจุบัน!
rostamiani

@HelloWorld - จะวางตรรกะในเชิงมุม 7 ได้ที่ไหน?
Pra_A

ไม่สำคัญว่าเวอร์ชันเชิงมุมใด - นี่เป็นเพียงรหัส js ปกติเท่านั้น
HelloWorld

ใส่ฟังก์ชั่นคลิก window.location.href = '/' หรือ '/ login' ซึ่งเคยกำหนดไว้ภายใน app-Routing.module.ts ในกรณีของฉันเมื่อผู้ใช้ออกจากระบบควรกลับไปที่หน้าจอเข้าสู่ระบบดังนั้นเมื่อออกจากระบบฉันจะล้างข้อมูลการตรวจสอบสิทธิ์ทั้งหมดและเมื่อประสบความสำเร็จให้ใช้ window.location.href = '/' ซึ่งหมายความว่าโหลดหน้า loagin ซ้ำและเรียกใช้ javascript ทั้งหมดอีกครั้ง สำหรับการเปลี่ยนเส้นทางตามปกติฉันจะไม่แนะนำสิ่งนี้ในกรณีที่ไม่จำเป็นต้องเรียกใช้ฟังก์ชันซ้ำ
Ali Exalter

ฉันเชื่อว่านี่อาจรีเซ็ตที่เก็บ NgRx ของคุณโดยสมบูรณ์ดังนั้นข้อมูลใด ๆ ที่คุณดึงมาแล้วจะสูญหาย
John Q

3

สำหรับฉันทำงานฮาร์ดโค้ดด้วย

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

2
ไม่แนะนำ! ผู้คนยังคงโพสต์โซลูชันนี้ซ้ำในรูปแบบต่างๆตลอด SO นี้ ใช่มันอาจแก้ไขปัญหาเฉพาะหน้าของคุณได้ แต่คุณจะลืมในภายหลังว่าคุณได้ใช้สิ่งนี้และคุณจะใช้เวลาหลายชั่วโมงในการค้นหาสาเหตุที่แอปของคุณประสบกับพฤติกรรมแปลก ๆ
Post Impatica

หากคุณต้องใช้วิธีนี้ให้ใช้โซลูชันของ Ebraheem Alrabee และใช้กับเส้นทางเดียวเท่านั้น
Post Impatica

3

พบวิธีแก้ปัญหาที่รวดเร็วและตรงไปตรงมาซึ่งไม่ต้องใช้คนจรจัดกับการทำงานด้านในของเชิงมุม:

โดยทั่วไป: เพียงสร้างเส้นทางอื่นด้วยโมดูลปลายทางเดียวกันและเพียงแค่สลับระหว่างเส้นทาง:

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

และนี่คือเมนูสลับ:

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

หวังว่าจะช่วยได้ :)


จะเกิดอะไรขึ้นถ้าเส้นทางอื่นมีพารามิเตอร์และคุณต้องการโหลดใหม่เมื่อพารามิเตอร์เปลี่ยนแปลง?
Mukus

3

ไม่ยอมใครง่ายๆ แต่

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

    this.router.onSameUrlNavigation = 'ignore';

});

2

ในกรณีของฉัน:

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

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

ทำงานถูกต้อง


2

ใช้ OnInit และเรียก ngOnInit () ในวิธีการสำหรับ route.navigate ()

ดูตัวอย่าง:

export class Component implements OnInit {

  constructor() {   }

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

  ngOnInit () {

  }

2

แก้ไขสถานการณ์ที่คล้ายกันโดยใช้ส่วนประกอบจำลองและเส้นทางสำหรับreloadซึ่งทำไฟล์redirect. สิ่งนี้ไม่ครอบคลุมสถานการณ์ของผู้ใช้ทั้งหมดอย่างแน่นอน แต่ใช้ได้กับสถานการณ์ของฉัน

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);
  }
}

การกำหนดเส้นทางมีสายเพื่อตรวจจับ URL ทั้งหมดโดยใช้สัญลักษณ์แทน:

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 {}

ในการใช้สิ่งนี้เราต้องเพิ่มการโหลดซ้ำใน url ที่เราต้องการไป:

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

2

วิธีแก้ปัญหาคือการส่งพารามิเตอร์ดัมมี่ (เช่นเวลาเป็นวินาที) ด้วยวิธีนี้ลิงก์จะโหลดซ้ำเสมอ:

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

2

มีวิธีต่างๆในการรีเฟรชเส้นทางปัจจุบัน

เปลี่ยนพฤติกรรมของเราเตอร์ (ตั้งแต่ Angular 5.1) ตั้งค่าเราเตอร์บนSameUrlNavigationเป็น 'โหลดซ้ำ' สิ่งนี้จะแสดงเหตุการณ์ของเราเตอร์ในการนำทาง URL เดียวกัน

  • จากนั้นคุณสามารถจัดการได้โดยสมัครรับเส้นทาง
  • คุณสามารถใช้มันร่วมกับ runGuardsAndResolvers เพื่อเรียกใช้ตัวแก้ไขซ้ำ

ปล่อยให้เราเตอร์ไม่ถูกแตะต้อง

  • ส่งรีเฟรช queryParam ด้วยการประทับเวลาปัจจุบันใน URL และสมัครสมาชิก queryParams ในองค์ประกอบเส้นทางของคุณ
  • ใช้เหตุการณ์เปิดใช้งานของเราเตอร์เต้าเสียบเพื่อรับส่วนประกอบที่กำหนดเส้นทางไว้

ฉันได้เขียนคำอธิบายโดยละเอียดเพิ่มเติมในhttps://medium.com/@kevinkreuzer/refresh-current-route-in-angular-512a19d58f6e

หวังว่านี่จะช่วยได้


2

ฉันกำลังใช้setTimeoutและnavigationByUrlเพื่อแก้ปัญหานี้ ... และมันก็ใช้ได้ดีสำหรับฉัน

มันถูกเปลี่ยนเส้นทางไปยัง URL อื่นและกลับมาอีกครั้งใน URL ปัจจุบัน ...

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

1

สมมติว่าเส้นทางของคอมโพเนนต์ที่คุณต้องการรีเฟรชคือviewจากนั้นใช้สิ่งนี้:

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);
}; 

คุณสามารถเพิ่มภายในวิธีการที่จะรู้ว่าสิ่งที่เป็นเส้นทางที่แน่นอนจะมาหลังจากไปที่debugger"departments/:id/employees"


1

ทำลายมากว่าเชิงมุมยังดูเหมือนจะไม่รวมถึงการเป็นทางออกที่ดีสำหรับเรื่องนี้ ฉันได้ยกปัญหา github ที่นี่: https://github.com/angular/angular/issues/31843

ในระหว่างนี้นี่เป็นวิธีแก้ปัญหาของฉัน มันสร้างจากโซลูชันอื่น ๆ ที่แนะนำข้างต้น แต่ฉันคิดว่ามันแข็งแกร่งกว่าเล็กน้อย มันเกี่ยวข้องกับการรวมบริการเราเตอร์ไว้ใน " ReloadRouter" ซึ่งจะดูแลฟังก์ชันการโหลดซ้ำและยังเพิ่ม a RELOAD_PLACEHOLDERในการกำหนดค่าเราเตอร์หลัก ใช้สำหรับการนำทางชั่วคราวและหลีกเลี่ยงการทริกเกอร์เส้นทางอื่น ๆ (หรือยาม)

หมายเหตุ:ใช้เฉพาะReloadRouterในกรณีเหล่านั้นเมื่อคุณต้องการฟังก์ชันการโหลดซ้ำ ใช้ปกติRouterอย่างอื่น

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

นำเข้าRouterและActivatedRouteจาก@angular/router

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

ฉีดRouterและActivatedRoute(ในกรณีที่คุณต้องการอะไรจาก URL)

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

รับพารามิเตอร์ใด ๆ หากจำเป็นจาก URL

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

การใช้เคล็ดลับโดยไปที่ดัมมี่หรือ URL หลักจากนั้นไปยัง URL จริงจะรีเฟรชคอมโพเนนต์

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

ในกรณีของคุณ

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

หากคุณใช้เส้นทางจำลองคุณจะเห็นชื่อเรื่องกะพริบ "ไม่พบ" หากคุณใช้ url ที่ไม่พบในกรณีที่ไม่ตรงกับ url ใด ๆ


0

สมัครรับข้อมูลการเปลี่ยนแปลงพารามิเตอร์เส้นทาง

    // 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

หากคุณกำลังเปลี่ยนเส้นทางผ่านRouter Link ให้ทำตามนี้:

  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

ฉันเชื่อว่าสิ่งนี้ได้รับการแก้ไขแล้ว (โดยกำเนิด) ใน Angular 6+; ตรวจสอบ

แต่ใช้ได้กับทั้งเส้นทาง (รวมถึงเส้นทางเด็กทั้งหมดด้วย)

หากคุณต้องการกำหนดเป้าหมายองค์ประกอบเดียวให้ทำดังนี้: ใช้พารามิเตอร์การค้นหาที่เปลี่ยนแปลงเพื่อให้คุณนำทางได้หลายครั้งเท่าที่คุณต้องการ

ที่จุดนำทาง (ชั้นเรียน)

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

ในคอมโพเนนต์ที่คุณต้องการ "รีเฟรช / โหลดซ้ำ"

// . . . 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

ที่น่าสนใจวิธีนี้จะใช้ได้เพียงครั้งเดียวดูเหมือนว่ามีข้อบกพร่องใน Angular ซึ่งqueryParamsMapหัวเรื่องจะได้รับการอัปเดตในครั้งแรกเท่านั้น แต่จะไม่อัปเดตในภายหลัง
Andrew Gray

0

ตัดสินใจว่าเมื่อใดควรจัดเก็บเส้นทางกลับเป็นเท็จ

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

และตั้งค่าการนำทางของเราเตอร์เป็นเท็จซึ่งแสดงว่าเส้นทางนี้ไม่เคยกำหนดเส้นทาง

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

0

ฉันได้ลองแก้ไขสองสามครั้งแล้ว แต่ก็ไม่ได้ผล เวอร์ชันของฉันเรียบง่าย: เพิ่มพารามิเตอร์ใหม่ที่ไม่ได้ใช้ลงในพารามิเตอร์การค้นหา

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

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

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

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


-1

รหัสด้านล่างนี้จะใช้งานได้:

logoFn(url: any) {

    this.router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
    };
    this.router.navigate(['']); or
    this.router.navigate([url]);

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.