Yönlendirici Navigate, aynı sayfa olduğunda ngOnInit'i çağırmıyor


89

router.navigateBazı sorgu dizesi parametreleriyle aynı sayfada arıyorum . Bu durumda ngOnInit()aramaz. Varsayılan olarak mı yoksa başka bir şey eklemem gerekiyor mu?

Yanıtlar:


139

Enjekte edebilir ActivatedRouteve abone olabilirsinizparams

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

Yönlendirici, yalnızca farklı bir rotaya gittiğinde bileşeni yok eder ve yeniden oluşturur. Yalnızca yol parametreleri veya sorgu parametreleri güncellendiğinde ancak rota aynı olduğunda, bileşen yok edilmeyecek ve yeniden oluşturulmayacaktır.

Bileşeni yeniden oluşturulmaya zorlamanın alternatif bir yolu, özel bir yeniden kullanım stratejisi kullanmaktır. Ayrıca bkz aynı url farklı parametrelerle yüklendiğinde 2.0.0 yeniden değil bileşenleri yönlendirici Angular2? (henüz nasıl uygulanacağı konusunda çok fazla bilgi yok gibi görünüyor)


1
bu abonelik çalışmıyor, yalnızca başlangıçta tetiklenecek
Osanda Wedamulla

@OsandaWedamulla bu kodunuza özeldir. Daha fazla ayrıntı olmadan anlatmak zor
Günter Zöchbauer

1
Bunun için de aboneliğinizi iptal etmenize gerek yok mu yoksa bu otomatik olarak mı yapılır?
rain01

1
@ rain01 genel bir kural olarak, açıkça abone olduğunuzda cpde'nizdeki aboneliğinizi açıkça iptal etmelisiniz. Kök bileşeninizde yukarıdaki kodunuz varsa, abonelikten çıkma gereksizdir çünkü kök bileşenin ömrü genellikle tüm Angular uygulamasının yaşam süresiyle aynıdır.
Günter Zöchbauer

Bu çözüm, stackoverflow.com/a/47827668/5284473 (veya global olarak onSameUrlNavigation ayarı) ile birleştirildiğinde çalışır .
S. Roose

105

Yönlendiricide reuseStrategy'yi ayarlayabilirsiniz.

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

2
Bu, sayfadaki her bileşenin ngInit'ini başlatacaktır.
jforjs

3
Peki, @Pascal, cevabınızı artırmak için beni SO'da oturum açmaya zorladınız. Ben açısal 6'da da eklemek gerekir eklersiniz onSameUrlNavigation: 'reload'şöyle yapılandırma nesnesine: RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'}). Yine de başka herhangi bir Angular versiyon için konuşmuyorum.
Hildy

1
@Hildy, ben de aynısını yapmak zorunda kaldım :) Teşekkürler @Pascal! lambda'yı tercih ediyorsanız, bunu yapabilirsiniz this.router.routeReuseStrategy.shouldReuseRoute = () => false;
nick

1
@Swaprks bir routing.module.ts oluşturdum ve kodu bu kurucu olarak yerleştirdim
Pascal

2
@Swaprks .. Benzer bir sorunum var ve cevabınızı yukarıda denemek istiyorum. Ama bu alanda yeni başlayan biri olarak bana pek bir şey anlatmıyor. Bu kod parçasını kodun tam olarak neresine yerleştirmem gerekiyor? Kod parçacığındaki herhangi bir şeyi değiştirmem gerekiyor mu (örneğin, ´function () ´)? Routing.module.ts adıyla yeni bir dosya oluşturduysanız, diğer dosyalarla nasıl etkileşime girmesi gerekiyor? Ayrıca otomatik olarak oluşturulan app-routing.module.ts adında bir dosya da vardır.
edn

24

Açısal 9

Aşağıdakileri kullandım ve işe yaradı.

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

1
Ek olarak, yukarıdaki yerine lambda da kullanın, this.router.routeReuseStrategy.shouldReuseRoute = () => false;
Dhwanil Patel

Angular 8'de çalışıyor.
Kishan Vaishnav

3
Bu, uygulama genelinde yönlendirici davranışını değiştirir mi, yoksa bu belirli için yalnızca bir kez tetikler navigate()mi?
Halfist

Angular 9'da çalışıyor
Ilija Iličić

9

Muhtemelen sayfayı yeniden yüklemeye ihtiyacınız var mı? Bu benim çözümüm: @NgModule'u değiştirdim ( benim durumumda app- routing.module.ts dosyasında):

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

Buradaki 'rotalar' nedir?
Dhwanil Patel

@DhwanilPatel, Angular uygulama rotalarınız. Örneğin "sabit yolları: yolları = [{yol: 'kriz merkezi', bileşen: CrisisListComponent}, {yol 'kahraman', bileşen: HeroListComponent},]" angular.io/guide/router#register-router-and rotalar
Dionis Oros

1

NgOnInitbir örnek oluşturulduğunda bir kez çağrılır. Aynı örnek bir NgOnInitdaha çağrılmayacak. Çağırmak için yaratılan örneği yok etmek gerekir.


1

Navigasyon yönteminizde,

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

1

Aynı sorunu yaşadım, ayrıca şu uyarıyı aldım:

did you forget to call `ngZone.run()`

Bu site en iyi çözümü sağladı:

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

Bununla ilgili olarak, sayfayı yeni rotayla yenilediğinizde sorunun nasıl çözüleceğini bilmek istiyorum. Bu durumda, NgZone uyarısı hala mevcut olacaktır.
Siddhant

0

Bu sorun büyük olasılıkla ngOnDestroy kullanarak aboneliklerinizi sonlandırmadığınız gerçeğinden kaynaklanmaktadır. İşte nasıl yapılacağı.

  1. Aşağıdaki rxjs abonelik içe aktarmayı getirin. import { Subscription } from 'rxjs/Subscription';

  2. Açısal Çekirdek Aktarımınıza OnDestory ekleyin. import { Component, OnDestroy, OnInit } from '@angular/core';

  3. OnDestory'yi dışa aktarma sınıfınıza ekleyin. export class DisplayComponent implements OnInit, OnDestroy {

  4. Bileşendeki her abonelik için dışa aktarma sınıfınız altında rxjs'den Abonelik değerine sahip bir nesne özelliği oluşturun. myVariable: Subscription;

  5. Aboneliğinizin değerini MyVariable: Subscriptions olarak ayarlayın. this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});

  6. Ardından ngOninit'in hemen altına ngOnDestory () yaşam döngüsü kancasını yerleştirin ve aboneliğiniz için abonelikten çıkma bildiriminizi yerleştirin. Birden fazla varsa, daha fazlasını ekleyin ngOnDestroy() { this.myVariable.unsubscribe(); }


Ben ngOnDestoryde ngOnDestroykendim yerine yazmaya devam ediyorum ;-)
Simon_Weaver

0

Route dizisindeki aynı bileşen için farklı bir yol oluşturun.

const yolları: Rotalar = [{yol: "uygulama", bileşen: Bileşenim}, {yol: "uygulama yeniden yükleme", bileşen: Bileşenim}];

Mevcut URL "uygulama" ise "uygulamayı yeniden yükle" seçeneğini kullanarak gezinin veya bunun tersini yapın.


0

İşte bu sayfadaki en iyi fikirlerin bir koleksiyonu ve daha fazla bilgi

1.Çözüm - Params aboneliğini kullanın:

Eğitici: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters

Dokümanlar: https://angular.io/api/router/ActivatedRoute#params

Param değişkenleri kullanan yönlendirme bileşenlerinizin her birinde aşağıdakileri içerir:

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

Bu kodla ilgili bazı yaygın sorunlar, aboneliklerin eşzamansız olması ve başa çıkmanın daha zor olabilmesidir. Ayrıca ngOnDestroy'da aboneliğinizi iptal etmeyi unutamazsınız, aksi takdirde kötü şeyler olabilir.

İyi olan şey, bu sorunu çözmenin en yaygın ve belgelenmiş yolu olmasıdır. Ayrıca, bir sayfayı her ziyaret ettiğinizde yok etmek ve yeniden oluşturmak yerine şablonu yeniden kullandığınız için, bunu bu şekilde yapan bir performans iyileştirmesi de vardır.

2.Çözüm - shouldReuseRoute / onSameUrlNavigation:

Dokümanlar: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation

Dokümanlar: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute

Dokümanlar: https://angular.io/api/router/ActivatedRouteSnapshot#params

RouterModule.forRootProjenizde nerede olduğunu bulun (normalde app-routing.module.ts veya app.module.ts'de bulunur):

const routes: Routes = [
   // ...
];

// ...

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

Ardından AppComponent'te aşağıdakileri ekleyin:

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

        // ...
    }

    // ...
}

Son olarak, yönlendirme bileşenlerinizde artık param değişkenlerini şu şekilde işleyebilirsiniz:

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;

        // ...
    }

    // ...
}

Bu çözümle ilgili yaygın sorunlar, yaygın olmamasıdır. Ayrıca Angular çerçevenin varsayılan davranışını değiştiriyorsunuz, böylece insanların normalde karşılaşmayacağı sorunlarla karşılaşabilirsiniz.

İyi olan şey, tüm kodunuzun eşzamanlı olması ve anlaşılması daha kolaydır.


-1

NgOnInit'te sahip olduğunuz kodu ngAfterViewInit'e taşımayı düşünün. İkincisi, yönlendirici navigasyonunda çağrılıyor gibi görünüyor ve bu durumda size yardımcı olmalı.


3
bu gerçekten olmaz
nadav

-7

Yönlendirici aynı sayfada gezinmek istediğinizde ve ngOnInit () 'i çağırmak istediğinizde, bunu seversiniz, örneğin,

this.router.navigate (['kategori / liste', kategori]) .then (() => window.location.reload ());

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.