Jak odświeżyć komponent w Angular


86

Pracuję nad projektem Angular. Zmagam się z działaniem odświeżania w komponencie.

Chciałbym odświeżyć komponenty routera po kliknięciu przycisku. Mam przycisk odświeżania, kiedy klikam na niego, komponent / router wymaga odświeżenia.

Spróbowałem window.location.reload()i location.reload()te dwa nie są odpowiednie dla moich potrzeb. Proszę o pomoc, jeśli ktoś o tym wie.


Czy możesz udostępnić swój kod w tym pytaniu? czego próbujesz.
Chandru,

jest to złożony kod, ma numer N linii kodu, trudny do udostępnienia
Sreehari Ballampalli

@Saurabh, zwykle nie jest konieczne ponowne ładowanie komponentu. Możesz mieć funkcję (np. Wywołanie „restartu”) i wywołać funkcję w swoim przycisku Odśwież. Jeśli potrzebujesz subskrybować, aby zmienić ścieżkę lub inną usługę, użyj funkcji ngOnInit - twój komponent musi rozszerzać OnInit-, a nie konstruktor
Eliseo

Oto, co zrobiłem z Angular 9 stackoverflow.com/a/60909777/1072395
Wlada

Odpowiedzi:


115

Po kilku badaniach i zmodyfikowaniu mojego kodu, jak poniżej, skrypt zadziałał. Właśnie dodałem warunek:

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

1
Używam tego w usłudze do wstrzykiwania. Zastąpiłem "your actualComponent"zmienną. Zmienna jest ustawiana na this.location.path()przed wywołaniem navigateByUrl. W ten sposób nie ma potrzeby przekazywania żadnych parametrów z wywołującego komponentu ani duplikowania / przekazywania tras.
Tewr

4
czy możesz wyjaśnić, co to jest „RefrshComponent” i „Twój rzeczywisty składnik”?
reverie_ss

15
Prawie każdemu będzie dobrze, używając '/'gdzie /RefrshComponentjest, a [Your actualComponent"]Ty po prostu przekażesz adres URL (i / lub parametry), które chcesz przeładować, takie jak this.router.navigate(["/items"]). Ten hack zasadniczo przekierowuje do górnego adresu URL, a następnie bardzo szybko z powrotem do zamierzonego adresu URL, który jest niezauważalny dla większości użytkowników i wydaje się być najbardziej eleganckim sposobem na osiągnięcie tego celu.
łagodnie

2
Zgadzam się, że to zdecydowanie powinno działać ... ale nie działa w mojej aplikacji (Angular 6). Jeśli używam '/'jako mojej fałszywej trasy, przechodzi ona (przez redirectTo) do miejsca, w którym mój app-routing.module.ts przekierowuje na ścieżkę ''(pusty ciąg) i zatrzymuje się, nie przechodząc do trasy zakończenia w navigate()wywołaniu. Jeśli użyję nieistniejącego ciągu (np. /foo) Jako mojej fałszywej trasy, przechodzi (przez redirectTo) do miejsca, w którym moja aplikacja-routing.module.ts przekierowuje **(wszystko inne) i ponownie zatrzymuje się, nie idąc na prawdziwą trasę. Co ciekawe, pasek adresu URL zmienia się na rzeczywistą trasę. Jakieś przemyślenia na temat tego, co tu się różni?
Michael Sorens

1
może to spowodować nieskończoną pętlę przekierowań, jeśli nie jest używane ostrożnie
Tomas Katz

66

Użyj this.ngOnInit (); aby przeładować ten sam komponent zamiast przeładowywać całą stronę !!

DeleteEmployee(id:number)
  {
    this.employeeService.deleteEmployee(id)
    .subscribe( 
      (data) =>{
        console.log(data);

        this.ngOnInit();

      }),
      err => {
        console.log("Error");
      }   
  }

7
Chociaż może to odpowiedzieć na pytanie autorów, brakuje w nim słów wyjaśniających i / lub linków do dokumentacji. Fragmenty surowego kodu nie są zbyt pomocne bez otaczających je fraz. Może się również okazać, że bardzo pomocne może być napisanie dobrej odpowiedzi . Zmień swoją odpowiedź.
witaj

1
Jest to lepszy wkład niż wybrana odpowiedź, ale brakuje mu wyjaśnienia. W moim konkretnym przypadku musiałem odświeżyć komponent podrzędny. W takim przypadku jest kilka sposobów, ale zalecane jest skorzystanie z usługi lub transmitowanie wydarzenia od rodzica do dziecka.
Claudio

5
Zgoda, działa to tylko wtedy, gdy chcesz odświeżyć komponent z poziomu komponentu - jeśli masz do czynienia z komponentami podrzędnymi / zewnętrznymi, this.ngOnInit () nie będzie działać
astro8891

3
Mimo że działa dla komponentu, nie resetuje walidatorów formularzy.
Vicky Gonsalves,

1
Działa idealnie, dziękuję. A jeśli chodzi o wyjaśnienie AFAIC, kod mówi wszystko.
Marton Tatai

27

Dodanie tego do kodu do konstruktora wymaganego komponentu działało dla mnie.

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

this.mySubscription = this.router.events.subscribe((event) => {
  if (event instanceof NavigationEnd) {
    // Trick the Router into believing it's last link wasn't previously loaded
    this.router.navigated = false;
  }
});

Upewnij się, że unsubscribez tego mySubscription w ngOnDestroy().

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

Więcej informacji można znaleźć w tym wątku - https://github.com/angular/angular/issues/13831


15

Na szczęście, jeśli używasz Angular 5.1+, nie musisz już implementować hacka, ponieważ dodano natywną obsługę. Musisz tylko ustawić onSameUrlNavigation na 'przeładowanie' w opcjach RouterModule:

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

Więcej informacji można znaleźć tutaj: https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2


Możesz również użyć router.onSameUrlNavigation = 'reload'właściwości wstrzykniętego routera.
0zkr PM

4
Używając kątowej 6, dla mnie to nie miało znaczenia, to znaczy, że komponent nie przeładował się. Zaakceptowana odpowiedź działa jednak.
Tewr

4
Chociaż nie jest to całkowicie jasne w dokumentacji, onSameUrlNavigationma na celu ponowne wezwanie Strażników / Resolwerów, a nie przeładowywanie już rozbitych komponentów. Więcej informacji na ten temat znajdziesz na github.com/angular/angular/issues/21115 . To rozwiązanie będzie działać w przypadku większych, bardziej złożonych aplikacji korzystających z zabezpieczeń / resolwerów, ale zawiedzie w przypadku prostych przykładów.
łagodnie

1
tak, onSameUrlNavigation ponownie uruchomi zdarzenia nawigacji, ale to nie przeładuje komponentu
Paul Story

6

to jest trochę po wyjęciu z pudełka i nie wiem, czy to ci pomoże, czy nie, ale próbowałem

this.ngOnInit();

jest to funkcja, więc każdy kod, który w niej masz, zostanie przywołany tak jak odświeżenie.


3

Jeszcze jeden sposób bez wyraźnej trasy:

async reload(url: string): Promise<boolean> {
  await this.router.navigateByUrl('.', { skipLocationChange: true });
  return this.router.navigateByUrl(url);
}

2

Można to osiągnąć poprzez włamanie, przejdź do jakiegoś przykładowego komponentu, a następnie przejdź do komponentu, który chcesz ponownie załadować.

this.router.navigateByUrl('/SampleComponent', { skipLocationChange: true });
this.router.navigate(["yourLandingComponent"]);

SampleComponent oznacza, że ​​powinien to być pusty komponent lub inny komponent w moim projekcie?
Sreehari Ballampalli,

powinien być atrapą, może być pusty
Sajeetharan

Ok, spróbuję tego
Sreehari Ballampalli

jeśli podam prawdę, otrzymuję komunikat o błędzie: [ts] Typ „true” nie ma właściwości wspólnych z typem „NavigationExtras”
Sreehari Ballampalli

@SreehariBallampalli sprawdź zaktualizowaną odpowiedź, musisz przekazać obiekt {skipLocationChange: true}
Sajeetharan,

2

W mojej aplikacji mam komponent, a wszystkie dane pochodzą z API, które wywołuję w konstruktorze komponentu. Jest przycisk, za pomocą którego aktualizuję dane mojej strony. po kliknięciu przycisku zapisuję dane w zapleczu i odświeżam dane. Więc przeładowanie / odświeżenie komponentu - zgodnie z moim wymaganiem - jest tylko odświeżeniem danych. jeśli jest to również Twoje wymaganie, użyj tego samego kodu zapisanego w konstruktorze komponentu.


2

po prostu zrób to: (dla kątowej 9)

import { Inject } from '@angular/core';    
import { DOCUMENT } from '@angular/common';

constructor(@Inject(DOCUMENT) private document: Document){ }

someMethode(){ this.document.location.reload(); }

3
Proszę przeczytać komentarz OPs, odświeżanie całej strony nie wchodzi w grę dla niego, to mija się z celem posiadania kąta na pierwszym miejscu
ihorbond

Pytanie dotyczy przeładowania komponentu tylko nie całej strony.
Santosh

1

kdo

// reload page hack methode

push(uri: string) {
    this.location.replaceState(uri) // force replace and no show change
    await this.router.navigate([uri, { "refresh": (new Date).getTime() }]);
    this.location.replaceState(uri) // replace
  }

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

onReload(){
 this.router.navigate(['/servers'],{relativeTo:this.route})
}

0

html

<a (click)= "getcoursedetails(obj.Id)" routerLinkActive="active" class="btn btn-danger">Read more...</a>

ts plik

  getcoursedetails(id)
  { 
  this._route.navigateByUrl('/RefreshComponent', { skipLocationChange: true }).then(() => {
    this._route.navigate(["course",id]);
  }); 

0

Po prostu zmień routeReuseStrategy z kątowego routera:

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

Ustaw właściwość routera „navigated” na false:

this._router.navigated = false;

Następnie przejdź do swojego komponentu:

this._router.navigate(['routeToYourComponent'])

Następnie przywróć starą / domyślną routeReuseStrategy:

this._router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
          return future.routeConfig === curr.routeConfig;

Możesz również wykonać usługę z tego:

@Injectable({
  providedIn: 'root'
})
export class RouterService {

  constructor(
    private _activatedRoute: ActivatedRoute,
    private _router: Router
  ) { }

  reuseRoutes(reuse: boolean) {
    if (!reuse) {
      this._router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
      };
    }
    if (reuse) {
      this._router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig;
      };
    }
  }

  async refreshPage(url?: string) {
    this._router.routeReuseStrategy.shouldReuseRoute = function () {
      return false;
    };

    this._router.navigated = false;

    url ? await this._router.navigate([url]) : await this._router.navigate([], { relativeTo: this._activatedRoute });

    this._router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
      return future.routeConfig === curr.routeConfig;
    };
  }
}

0

W moim przypadku chciałem refresh the whole pagezamiast tylko komponentu, więc tak to zrobiłem

window.location.reload();


0

router.navigate['/path']będzie można dostać się tylko do określonej ścieżki
wykorzystania router.navigateByUrl('/path')
go przeładowuje całą stronę


-3

Innym sposobem na odświeżenie (trudny sposób) strony w kątowej 2, takiej jak ten , jest f5

import { Location } from '@angular/common';

constructor(private location: Location) {}

pageRefresh() {
   location.reload();
}

1
Powiedział, że ponowne załadowanie całej strony jest nieodpowiednie, to przeładowuje całą stronę, a nie tylko jeden / wiele składników.
Milan Velebit,

Skończyło się na tym, że korzystałem z tego, z wyjątkiem tego, że usługa lokalizacji kątowej nie ma przeładowania, więc użyłem okna.
Paul Story
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.