programing

Angular 2 라우터 이벤트 수신기

sourcejob 2023. 8. 2. 09:02
반응형

Angular 2 라우터 이벤트 수신기

Angular 2 라우터에서 상태 변화를 청취하는 방법은 무엇입니까?

Angular 1.x에서 사용한 이벤트는 다음과 같습니다.

$rootScope.$on('$stateChangeStart',
    function(event,toState,toParams,fromState,fromParams, options){ ... })

Angular 2에서 이 이벤트 수신기를 사용하면 다음과 같습니다.

window.addEventListener("hashchange", () => {return console.log('ok')}, false);

'ok'를 반환하지 않고 JS에서 상태를 변경한 다음 브라우저 history.back() 함수만 실행됩니다.

라우터를 사용합니다.subscribe() 서비스로서의 기능:

import {Injectable} from 'angular2/core';
import {Router} from 'angular2/router';

@Injectable()
export class SubscribeService {
    constructor (private _router: Router) {
        this._router.subscribe(val => {
            console.info(val, '<-- subscribe func');
        })
    }
}

라우팅에서 init하는 구성 요소에 서비스 주입:

import {Component} from 'angular2/core';
import {Router} from 'angular2/router';

@Component({
    selector: 'main',
    templateUrl: '../templates/main.html',
    providers: [SubscribeService]
})
export class MainComponent {
    constructor (private subscribeService: SubscribeService) {}
}

저는 이 예와 같은 다른 구성 요소에 이 서비스를 주입합니다.그러면 상태를 변경하면 console.info 서비스가 작동하지 않습니다.

내가 뭘 잘못했나요?

새 라우터

constructor(router:Router) {
  router.events.subscribe(event:Event => {
    if(event instanceof NavigationStart) {
    }
    // NavigationEnd
    // NavigationCancel
    // NavigationError
    // RoutesRecognized
  });
}

늙은

라우터를 주입하고 경로 변경 이벤트에 가입합니다.

import {Router} from 'angular2/router';

class MyComponent {
  constructor(router:Router) {
    router.subscribe(...)
  }
}

메모

새 라우터의 경우 가져오기를 잊지 마십시오.NavigationStart부터router모듈

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

왜냐하면 만약 당신이 그것을 수입하지 않는다면.instanceof작동하지 않고 오류가 발생합니다.NavigationStart is not defined상승할 것입니다.

참고 항목

또한 다음을 사용하여 이벤트를 필터링할 수 있습니다.filter().

하지만 그냥 사용하지 마세요.filter(e => e is NavigationEnd)

훨씬 더 나은 해결책은 '타입 가드'를 추가하는 것입니다.filter()다음과 같이:

 filter((e): e is NavigationEnd => e instanceof NavigationEnd), 

두 가지가 포함되어 있습니다.

  • e is NavigationEnd이것은 함수를 정의하는 주장입니다(이것은 타이프스크립트 구문이며 transfiled javascript에서 완전히 벗겨짐).
  • e instanceof NavigationEnd이것은 유형을 확인하는 실제 런타임 코드입니다.

이것의 좋은 점은 운영자들이 '파이프'를 더 내려간다는 것입니다.map아래 유형은 다음과 같습니다.NavigationEnd하지만 타입 가드가 없다면 당신은 타입을 갖게 될 것입니다.Event.

이벤트 유형을 하나만 확인하면 되는 경우 가장 깨끗한 방법입니다.이것은 컴파일러 오류를 방지하기 위해 엄격한 모드에서도 필요한 것으로 보입니다.

enter image description here

사용할 수 있습니다.instanceof@Gunter Zöchbauer의 대답대로

this.router.events.subscribe(event => {
  if(event instanceof NavigationStart) {
    // do something...
  }
}

또는 더 게으른 접근법을 사용할 수 있지만, 함수가 여전히 작동하는 동안 생성자 이름은 쉽게 변경될 수 있습니다!

this.router.events.subscribe(event => {
  if(event.constructor.name === "NavigationStart") {
    // do something...
  }
});

서류에서 바로.

import {Event, RouterEvent, Router, NavigationEnd} from '@angular/router';

this.router.events.pipe(
  filter((e: any): e is RouterEvent => e instanceof RouterEvent)
).subscribe((evt: RouterEvent) => {
  if (evt instanceof NavigationEnd) {
    console.log(evt.url)
  }
})

비록 문서들이 코드를 알려주지만,filter((e: Event)하지만 나는 이것을 변경했습니다.filter((e: any)또는 WebStorm에서 보풀 오류가 발생합니다.

import { Router,NavigationEnd  } from '@angular/router';
constructor(private route:Router){

  this.routeEvent(this.route);

}
routeEvent(router: Router){
  router.events.subscribe(e => {
    if(e instanceof NavigationEnd){
      console.log(e)
    }
  });
}

Angular 2 라우터 이벤트는 서로 다른 클래스를 가지고 있으며 서브스크립션에 전달되는 것은router.events관측 가능한 것은 다음 중 하나일 수 있습니다.NavigationEnd,NavigationCancel,NavigationError또는NavigationStart라우팅 업데이트를 실제로 트리거하는 것은 다음과 같습니다.NavigationEnd.

사용하지 않을 것입니다.instanceof또는event.constructor.name미니화 후 클래스 이름이 제대로 작동하지 않기 때문입니다.

라우터의 주소를 사용할 수 있습니다.isActive대신 기능, 여기에 표시됨 https://angular.io/docs/ts/latest/api/router/index/Router-class.html

this.routerEventSubscription = this._router.events.subscribe((event: any) => {
  if (this._router.isActive(events.url, false)) { 
    // true if the url route is active
  }
}

angular2에서 파일 "app.vmx.ts"->filename으로 이동합니다.

RouterModule.forRoot(
      appRoutes,
      { 
         enableTracing: true
      }
)

in enable true true show route enable의 콘솔에서 이벤트 추적false hide routeEvents 콘솔에서 이벤트 추적

@bespunky/angular-zen을 사용하면 훨씬 단순해집니다.

▁the다를 합니다.RouteAware 클스및생을 .on<EventType>()방법:

import { Component                                        } from '@angular/core';
import { NavigationStart, NavigationEnd, RoutesRecognized } from '@angular/router';
import { RouteAware                                       } from '@bespunky/angular-zen/router-x';

@Component({
    selector   : 'app-demo',
    templateUrl: './demo.component.html',
    styleUrls  : ['./demo.component.css']
})
export class DemoComponent extends RouteAware
{
    // ✨ Any router event can have a handler method.
    // See https://angular.io/guide/router#router-events for a complete list of angular's router events.

    // ✨ Use `this.router` to access the router
    // ✨ Use `this.route` to access the activated route
    // ✨ Use `this.componentBus` to access the RouterOutletComponentBus service
    
    protected onNavigationStart(event: NavigationStart): void
    {
        console.log(`Navigation started for: ${event.url}`);
    }

    protected onRoutesRecognized(event: RoutesRecognized): void
    {
        console.log('Recognized routes.');
    }
    
    protected onNavigationEnd(event: NavigationEnd): void
    {
        console.log(`Navigation ended for: ${event.url}`);
    }
}

다음 답변을 살펴보십시오. https://stackoverflow.com/a/64864103/4371525

모든 상태 변경을 청취하려면 기본 RouterOutlet을 확장하고 '활성화' 및 '비활성화' 처리기에 자체 로직을 추가합니다.

import {Directive} from 'angular2/core';
import {Router, RouterOutlet, ComponentInstruction} from 'angular2/router';

@Directive({
  selector: 'router-outlet'
})

export class MyOwnRouterOutlet extends RouterOutlet {
  ...

  activate() {
    console.log('Hello from the new router outlet!');
  }
}

'사용자 지정 라우터 아울렛' 예제에서 복사했습니다. https://auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/

언급URL : https://stackoverflow.com/questions/35912932/angular-2-router-event-listener

반응형