【Angular】router-outlet 로 호출된 Component 의 메소드를 이용한다

13067 단어 AngularAngular8

하고 싶은 일


<router-outlet> 에 표시되어 있는 Component 의 메소드를, template 에 <router-outlet> 를 이용하고 있는 Component 로부터 이용하고 싶다.

환경


  • Angular CLI 8.1.2
  • nodeJS 10.16.3
  • npm 4.0.5

  • 해결책


    RouterOutlet@Output('activate') 를 이용하면, Component 를 취득 가능했습니다.

    공식 사이트 설명↓

    A router outlet will emit an activate event any time a new component is being instantiated, and a deactivate event when it is being destroyed.
    acrtivate 이벤트는 Component가 인스턴스화될 때마다 호출되는 것 같습니다.
    이 이벤트로 취득할 수 있는 $event 에는 호출된 Component 가 포함되고 있어, $event<router-outlet> 를 보관 유지하고 있는 Component 의 보관 유지하는 것으로, Component 에 액세스 할 수가 있습니다.

    구체적인 구현



    이하, 동작을 확인한 소스를 기재합니다.

    루트 정의



    app-routing.module.ts
    import { NgModule } from "@angular/core";
    import { Routes, RouterModule } from "@angular/router";
    import { RoutingTestComponent } from "./routing-test/routing-test.component";
    import { FirstChildComponent } from "./first-child/first-child.component";
    import { SecondChildComponent } from "./second-child/second-child.component";
    
    const routes: Routes = [
      {
        path: 'routing',
        component: RoutingTestComponent,
        //  子ルートをchildrenで定義
        children: [
          { path: 'first', component: FirstChildComponent},
          { path: 'second', component: SecondChildComponent}
        ]
      }
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule {}
    
    

    template에서 <router-outlet>을 사용하는 Component



    routing-test.component.ts
    import { Component, OnInit } from "@angular/core";
    import { Router, ActivatedRoute } from "@angular/router";
    
    @Component({
      selector: "app-routing-test",
      template: `
        <p>routing-test</p>
        <button (click)="goFirstChild()">first child</button>
        <button (click)="goSecondChild()">second child</button>
        <button (click)="save()" [disabled]="componentRef == null">save</button>
        <!-- routesでchildrenとして定義したComponentは↓に表示される -->
        <router-outlet (activate)="onActivate($event)"></router-outlet>
      `
    })
    export class RoutingTestComponent implements OnInit {
      /**
       * router-outletにより呼び出されたComponentへの参照
       */
      private componentRef;
    
      constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
    
      ngOnInit() {}
    
      /**
       * FirstChildComponentへページ遷移
       */
      goFirstChild() {
        this.router.navigate(["first"], { relativeTo: this.activatedRoute });
      }
    
      /**
       * SecondChildComponentへページ遷移
       */
      goSecondChild() {
        this.router.navigate(["second"], { relativeTo: this.activatedRoute });
      }
    
      /**
       * 参照したComponentのsaveメソッドを呼び出す
       */
      save() {
        this.componentRef.save();
      }
    
      /**
       * router-outletによる画面切り替え時に呼び出される処理
       */
      onActivate(event) {
        // eventを通じて呼び出されたComponentを取得できる
        this.componentRef = event;
      }
    }
    

    <router-outlet>에 호출되는 측의 Component



    first-child.component.ts
    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-first-child',
      template: `<p>first child</p>`
    })
    export class FirstChildComponent implements OnInit {
    
      constructor() { }
    
      ngOnInit() {
      }
    
      save(){
        console.log("first");
      }
    }
    

    second-child.component.ts
    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-second-child',
      template: `<p>second child</p>`
    })
    export class SecondChildComponent implements OnInit {
    
      constructor() { }
    
      ngOnInit() {
      }
    
      save(){
        console.log("second");
      }
    }
    

    각 Component에 대응하는 메소드가 불려 가고 있는지 확인


  • FirstChild
  • SecondChild

  • 각 Component로 각각 정의한 save() 메소드가 불려 가고 있는 것을 확인할 수 있었습니다!

    참고 사이트



    Can you use @ViewChild() or similar with a router-outlet? How if so?
    RouterOutlet

    좋은 웹페이지 즐겨찾기