राउटर नेवेट उसी पेज पर ngOnInit को कॉल नहीं करता है


86

मैं router.navigateकुछ क्वेरी स्ट्रिंग मापदंडों के साथ एक ही पृष्ठ पर कॉल कर रहा हूं । इस मामले में, ngOnInit()कॉल नहीं करता है। क्या यह डिफ़ॉल्ट रूप से है या मुझे कुछ और जोड़ने की आवश्यकता है?

जवाबों:


136

आप इंजेक्शन लगा सकते हैं ActivatedRouteऔर सदस्यता ले सकते हैंparams

constructor(route:ActivatedRoute) {
  route.params.subscribe(val => {
    // put the code from `ngOnInit` here
  });
}

राउटर केवल घटक को नष्ट और पुन: बनाता है जब यह एक अलग मार्ग पर नेविगेट करता है। जब केवल रूट परमेस या क्वेरी परम अपडेट किए जाते हैं लेकिन मार्ग समान होता है, तो घटक को नष्ट नहीं किया जाएगा और फिर से बनाया जाएगा।

घटक को फिर से बनाने के लिए मजबूर करने का एक वैकल्पिक तरीका एक कस्टम पुन: उपयोग की रणनीति का उपयोग करना है। यह भी देखें कि Angular2 राउटर 2.0.0 घटकों को पुनः लोड नहीं कर रहा है जब एक ही url विभिन्न मापदंडों के साथ लोड किया गया है? (इसको लागू करने के बारे में अभी तक बहुत सी जानकारी उपलब्ध नहीं है)


1
यह सदस्यता केवल init पर ट्रिगर ट्रिगर wil काम नहीं कर रही है
Osanda Wedamulla

@OandaWedamulla आपके कोड के लिए विशिष्ट है। हालांकि अधिक जानकारी के बिना बताना मुश्किल है
Günter Zöchbauer

1
क्या आपको इससे भी सदस्यता समाप्त करने की आवश्यकता नहीं है या यह स्वचालित रूप से किया जाता है?
बारिश 01

1
@ बारिश के नियम के रूप में आपको स्पष्ट रूप से सदस्यता लेने पर आपको अपने सीपीपी में स्पष्ट रूप से सदस्यता समाप्त करनी चाहिए। यदि आपके रूट कंपोनेंट में कोड ऊपर है तो अनसब्सक्राइब करना बेमानी है क्योंकि रूट कंपोनेंट का जीवनकाल आमतौर पर पूरे एंगुलर ऐप के जीवनकाल के समान ही होता है।
गुंटर ज़ोचाउर

103

आप राउटर पर reuseStrategy को समायोजित कर सकते हैं।

constructor(private router: Router) {
    // override the route reuse strategy
    this.router.routeReuseStrategy.shouldReuseRoute = function() {
        return false;
    };
}

2
यह पृष्ठ पर प्रत्येक घटक के ngInit आरंभ करेगा।
jforjs

2
खैर, @ पास्कल, आपने मुझे एसओ को अपना जवाब देने के लिए लॉग-इन करने के लिए मजबूर किया। मुझे लगता है कि कोणीय 6 में आप भी onSameUrlNavigation: 'reload'इस तरह से कॉन्फ़िगर वस्तु में जोड़ना होगा RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'}):। हालांकि किसी अन्य कोणीय संस्करणों के लिए कॉड नहीं बोलते हैं।
हिल्डी

1
@ बच्चों, मैं ऐसा ही करने के लिए मजबूर था :) धन्यवाद @ पास्कल! यदि आप लैम्ब्डा पसंद करते हैं, तो आप यह कर सकते हैं। इस प्रकार। routeReuseStrategy.shouldReuseRoute = () => false;
निक

1
@ Swaprks मैंने एक रूटिंग.module.ts बनाया और इस कंस्ट्रक्टर के रूप में कोड रखा
पास्कल

1
@ स्वेच्छाचार्यों .. मेरे पास एक समान मुद्दा है और मैं आपके उत्तर की कोशिश करना चाहूंगा। लेकिन यह मुझे इस क्षेत्र में एक शुरुआत के रूप में ज्यादा नहीं बताता है। वास्तव में कोड में मैं इस कोड का टुकड़ा कहां रखने वाला हूं? क्या मुझे कोड स्निपेट (जैसे unctionfunction () to) में कुछ भी बदलना चाहिए? यदि आपने एक नई फ़ाइल का नाम routing.module.ts के साथ बनाया है, तो इसे अन्य फ़ाइलों के साथ इंटरैक्ट कैसे करना चाहिए? इसमें एक फाइल भी होती है, जिसे ऐप-राउटिंग.module.ts कहा जाता है जो कि स्वचालित रूप से बनाई गई है।
ईडी

21

कोणीय 9

मैंने निम्नलिखित का उपयोग किया है और यह काम किया है।

onButtonClick() {
    this.router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
    }
    this.router.onSameUrlNavigation = 'reload';
    this.router.navigate('/myroute', { queryParams: { index: 1 } });
}

1
इसके अलावा, ऊपर के बजाय लैम्ब्डा का भी उपयोग करें, यह .router.routeReuseStrategy.shouldReuseRoute = () => false;
धवनिल पटेल

कोणीय 8. में काम करता है
किशन वैष्णव

2
क्या यह पूरे अनुप्रयोग में राउटर व्यवहार को बदल देगा या इस विशिष्ट के लिए केवल एक बार ट्रिगर होगा navigate()?
हाफिस्ट

8

क्या आपको शायद पृष्ठ पुनः लोड करने की आवश्यकता है? यह मेरा समाधान है: मैंने @NgModule ( मेरे मामले में app-routing.module.ts फ़ाइल में) को बदल दिया है :

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

यहाँ पर 'मार्ग' क्या है।
धवनिल पटेल

@DhwanilPatel अपने कोणीय एप्लिकेशन मार्गों। उदाहरण के लिए "कास्ट रूट्स: रूट्स = [{पथ: 'संकट-केंद्र', घटक: क्राइसिसलिस्टकम्पोनेंट}, {पथ: 'हीरो', घटक: हीरोलीस्टम्पोनेंट},]" कोणीय.io/guide.router
ओरोस

1

NgOnInitएक बार एक उदाहरण बनाया जाता है जब बुलाया जाएगा। उसी उदाहरण के लिए NgOnInitफिर से कॉल नहीं किया जाएगा। इसे कॉल करने के लिए निर्मित उदाहरण को नष्ट करना आवश्यक है।


1

अपने नेविगेशन विधि पर,

this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});

1

मेरे पास एक ही मुद्दा है, इसके अतिरिक्त मुझे चेतावनी मिली:

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

इस संबंध में, मैं जानना चाहता हूं कि जब आप नए रूट के साथ पेज को रीफ्रेश करते हैं तो इस मुद्दे को कैसे हैंडल किया जाए। उस स्थिति में, NgZone चेतावनी अभी भी मौजूद होगी।
सिद्धांत

0

यह समस्या संभवतः इस तथ्य से आ रही है कि आप ngOnDestroy का उपयोग करके अपनी सदस्यता समाप्त नहीं कर रहे हैं। यह है कि कैसे किया जाए।

  1. निम्नलिखित rxjs सदस्यता आयात में लाओ। import { Subscription } from 'rxjs/Subscription';

  2. अपने कोणीय कोर आयात पर OnDestory जोड़ें। import { Component, OnDestroy, OnInit } from '@angular/core';

  3. अपने निर्यात वर्ग में OnDestory जोड़ें। export class DisplayComponent implements OnInit, OnDestroy {

  4. घटक पर प्रत्येक सदस्यता के लिए अपने निर्यात वर्ग के तहत rxjs से सदस्यता के मूल्य के साथ एक वस्तु संपत्ति बनाएँ। myVariable: Subscription;

  5. अपनी सदस्यता के मूल्य को MyVariable: सदस्यता के लिए सेट करें। this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});

  6. फिर ngOninit के ठीक नीचे ngOnDestory () जीवन चक्र हुक रखें और अपनी सदस्यता के लिए अपने सदस्यता समाप्त कथन में डालें। यदि आपके पास कई हैं, तो अधिक जोड़ें ngOnDestroy() { this.myVariable.unsubscribe(); }


मैं खुद के ngOnDestoryबजाय टाइपिंग ngOnDestroyभी करता रहता हूं ;-)
सिमोन_विवर

0

मार्गों सरणी में समान घटक के लिए एक अलग पथ बनाएं।

const मार्गों: मार्गों = [{पथ: "ऐप", घटक: MyComponent}, {path: "app-reload", घटक: MyComponent}];

यदि वर्तमान URL "ऐप" है, तो "ऐप-रीलोड" का उपयोग करके नेविगेट करें और इसके विपरीत।


0

अधिक जानकारी के साथ इस पृष्ठ पर सबसे अच्छे विचारों का संग्रह है

समाधान 1 - उपयोग परम सदस्यता:

ट्यूटोरियल: https://angular-2-training-book.rangle.io/rout/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#shouldReuse

डॉक्स: https://angular.io/api/router/ActivatedRouteSnapshot#params

RouterModule.forRootअपने प्रोजेक्ट में कहां स्थित है (सामान्य रूप से एप्लिकेशन- 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;

        // ...
    }

    // ...
}

इस समाधान के साथ सामान्य समस्या यह है कि यह आम नहीं है। इसके अलावा, आप कोणीय ढांचे के डिफ़ॉल्ट व्यवहार को बदल रहे हैं, इसलिए आप उन मुद्दों पर चल सकते हैं जो लोग सामान्य रूप से नहीं करेंगे।

अच्छी बात यह है कि आपका सभी कोड समकालिक और समझने में आसान है।


-1

उस कोड को स्थानांतरित करने पर विचार करें जो आपने ngOnInit में ngAfterViewInit में लिया था। बाद वाले को राउटर नेविगेशन कहा जाता है और आपको इस मामले में मदद करनी चाहिए।


3
यह वास्तव में नहीं होता है
nad

-7

जब आप राउटर को उसी पेज पर नेविगेट करना चाहते हैं और ngOnInit () पर कॉल करना चाहते हैं, तो आप इसे पसंद करते हैं जैसे,

this.router.navigate (['श्रेणी / सूची', श्रेणी]) .then () => window.location.reload ());

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.