라우터 탐색은 동일한 페이지에서 ngOnInit를 호출하지 않습니다.


90

router.navigate일부 쿼리 문자열 매개 변수를 사용하여 동일한 페이지에서 호출 하고 있습니다. 이 경우 ngOnInit()전화하지 않습니다. 기본적으로 설정되어 있습니까? 아니면 다른 항목을 추가해야합니까?

답변:


139

당신은 주입 ActivatedRoute하고 구독 할 수 있습니다params

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

라우터는 다른 경로로 이동할 때만 구성 요소를 파괴하고 재생성합니다. 경로 매개 변수 또는 쿼리 매개 변수 만 업데이트되지만 경로가 동일하면 구성 요소가 파괴되고 다시 생성되지 않습니다.

구성 요소를 강제로 다시 만드는 또 다른 방법은 사용자 지정 재사용 전략을 사용하는 것입니다. Angular2 라우터 2.0.0이 다른 매개 변수로 동일한 URL을로드 할 때 구성 요소를 다시로드하지 않음을 참조하십시오 . (아직 사용 가능한 정보가 많지 않은 것 같습니다. 구현 방법)


1
이 구독은 초기화 트리거 줘야 그것을 작동하지 않습니다
Osanda Wedamulla

@OsandaWedamulla는 귀하의 코드에만 해당됩니다. 하지만 자세한 내용은없이 말할 하드
귄터 Zöchbauer

1
이것도 구독을 취소 할 필요가 없나요? 아니면 자동으로 진행 되나요?
rain01

1
경험상 @ rain01은 명시 적으로 구독 할 때 cpde에서 명시 적으로 구독을 취소해야합니다. 루트 구성 요소에 위의 코드가 있으면 루트 구성 요소의 수명이 일반적으로 전체 Angular 앱의 수명과 동일하기 때문에 구독 취소가 중복됩니다.
Günter Zöchbauer

이 솔루션은 stackoverflow.com/a/47827668/5284473 (또는 onSameUrlNavigation 전역 설정) 과 결합 될 때 작동합니다 .
S. Roose

106

라우터에서 재사용 전략을 조정할 수 있습니다.

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

2
그러면 페이지에있는 모든 구성 요소의 ngInit가 시작됩니다.
jforjs

3
글쎄, @Pascal, 당신은 당신의 대답을 찬성하기 위해 SO에 로그인하도록 강요했습니다. Angular 6에서 다음 onSameUrlNavigation: 'reload'과 같이 구성 개체 에도 추가해야합니다 RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'}). 그러나 다른 Angular 버전에 대해서는 말할 수 없습니다.
Hildy

1
@Hildy, 나도 똑같이하도록 강요 받았다 :) @Pascal 감사합니다! 람다를 선호한다면 이것을 할 수 있습니다. this.router.routeReuseStrategy.shouldReuseRoute = () => false;
nick

1
@Swaprks가 나는 routing.module.ts을 만들고이 생성자로 코드를 삽입
파스칼

2
@Swaprks .. 비슷한 문제가 있으며 위의 답변을 시도하고 싶습니다. 하지만이 분야의 초보자로서 많은 것을 말해주지 않습니다. 이 코드 조각을 코드에서 정확히 어디에 배치해야합니까? 코드 스 니펫 (예 : ´function () ´)을 변경해야합니까? routing.module.ts라는 이름으로 새 파일을 만든 경우 다른 파일과 어떻게 상호 작용해야합니까? 자동으로 생성되는 app-routing.module.ts라는 파일도 있습니다.
edn

25

각도 9

나는 다음을 사용했고 그것은 효과가 있었다.

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

1
또한 위의 대신 람다를 사용하십시오. this.router.routeReuseStrategy.shouldReuseRoute = () => false;
Dhwanil Patel

각도 8에서 작동
Kishan Vaishnav

3
이로 인해 응용 프로그램 전체에서 라우터 동작이 변경 navigate()됩니까 아니면 이 특정 항목에 대해 한 번만 트리거 됩니까?
Halfist

Angular 9에서 작동합니다.
Ilija Iličić 20.11.

9

페이지를 다시로드해야합니까? 이것은 내 솔루션입니다 : 내가 변경 한 @NgModule을 (에 앱 routing.module.ts의 내 경우에는 파일) :

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

여기에있는 '경로'는 무엇입니까?
Dhwanil Patel

Angular 앱 경로를 @DhwanilPatel. 예를 들어 "const routes : Routes = [{path : 'crisis-center', component : CrisisListComponent}, {path : 'heroes', component : HeroListComponent},]" angular.io/guide/router#register-router-and -routes
Dionis Oros

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 경고가 계속 표시됩니다.
Siddhant

0

이 문제는 ngOnDestroy를 사용하여 구독을 종료하지 않는다는 사실에서 발생할 수 있습니다. 완료하는 방법은 다음과 같습니다.

  1. 다음 rxjs 구독 가져 오기를 가져옵니다. import { Subscription } from 'rxjs/Subscription';

  2. Angular Core Import에 OnDestory를 추가하십시오. import { Component, OnDestroy, OnInit } from '@angular/core';

  3. 내보내기 클래스에 OnDestory를 추가하십시오. export class DisplayComponent implements OnInit, OnDestroy {

  4. 구성 요소의 각 구독에 대한 내보내기 클래스 아래에서 rxjs의 Subscription 값을 사용하여 개체 속성을 만듭니다. myVariable: Subscription;

  5. 구독 값을 MyVariable : Subscriptions로 설정합니다. this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});

  6. 그런 다음 ngOninit 바로 아래에 ngOnDestory () 라이프 사이클 후크를 배치하고 구독에 대한 구독 취소 문을 입력합니다. 여러 개있는 경우 더 추가하십시오. ngOnDestroy() { this.myVariable.unsubscribe(); }


나는 계속 입력 ngOnDestory하는 대신 ngOnDestroy;-) 너무 자신
Simon_Weaver

0

route 배열의 동일한 구성 요소에 대해 다른 경로를 만듭니다.

const route : Routes = [{경로 : "app", 구성 요소 : MyComponent}, {경로 : "app-reload", 구성 요소 : MyComponent}];

현재 URL이 "app"이면 "app-reload"를 사용하여 탐색하고 그 반대의 경우도 마찬가지입니다.


0

여기에 더 많은 정보와 함께이 페이지의 최고의 아이디어 모음이 있습니다.

해결 방법 1-params 구독 사용 :

튜토리얼 : https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters

문서 : https://angular.io/api/router/ActivatedRoute#params

param 변수를 사용하는 각 라우팅 구성 요소에는 다음이 포함됩니다.

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#shouldReuseRoute

문서 : https://angular.io/api/router/ActivatedRouteSnapshot#params

RouterModule.forRoot프로젝트에서 위치를 찾습니다 (일반적으로 app-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;

        // ...
    }

    // ...
}

이 솔루션의 일반적인 문제는 일반적이지 않다는 것입니다. 또한 Angular 프레임 워크의 기본 동작을 변경하므로 사람들이 일반적으로 겪지 않는 문제에 부딪 힐 수 있습니다.

좋은 점은 모든 코드가 동기적이고 이해하기 쉽다는 것입니다.


-1

ngOnInit에있는 코드를 ngAfterViewInit로 이동하는 것을 고려하십시오. 후자는 라우터 탐색에서 호출되는 것으로 보이며이 경우 도움이 될 것입니다.


3
나던 정말 일어날 것을
nadav

-7

라우터가 같은 페이지에서 탐색하고 ngOnInit ()를 호출하고 싶을 때 예를 들어 다음과 같이합니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.