Angular面接のコーディング質問

Angularで兄弟コンポーネント間でデータを共有する方法は?

First(最初)というコンポーネントがあります。Firstコンポーネントの中にincrementという名前のボタンがあります。

もうひとつのSecond(第二)コンポーネントがあります。この中にはcount=0という変数があります。

面接官が求めているのは、Firstコンポーネントのincrementボタンをクリックすると、Secondコンポーネントのcount変数が増加し、それが反映されることです

どうやってそれを達成しますか?

import 'zone.js/dist/zone';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppService } from './app.service'

@Component({
  selector: 'my-first',
  template: `
    <h1>First</h1>
    <button>Increment</button>
  `,
  standalone: true,
  imports: [CommonModule],
})
export class First {
  name = 'Angular';
}

@Component({
  selector: 'my-second',
  template: `
    <h1>Second</h1>
    <h2>{{count}}</h2>
  `,
  standalone: true,
  imports: [CommonModule],
})
export class Second {
  count: number = 0;
  name = 'Angular';
}



@Component({
  selector: 'my-app',
  standalone: true,
  imports: [First, Second, CommonModule],
  providers: [AppService],
  template: `
    <h1>Hello from {{ name }}!</h1>
    <a target="_blank" href="https://angular.io/start">
      Learn more about Angular
    </a>
    <my-first></my-first>
    <my-second></my-second>
  `,
})
export class App {
  name = 'Angular';

  constructor(private appService: AppService) {
      console.log(this.appService.getData())
  }
}


bootstrapApplication(App);

こちらがそのコードです。
質問へのリンク - https://stackblitz.com/edit/stackblitz-starters-bxdzcr?file=src%2Fmain.ts

回答:

同じ結果を達成するにはさまざまな方法がありますが、もっとも簡単なのはサービスを通じる方法です。

Angularのサービスは親子関係にないコンポーネント間の通信を確立するために使用されます。

上記の面接の質問では、FirstとSecond両方が兄弟コンポーネントです。だからここではサービスを使用します。

  • 最初にサービス(app.service.tsとして)を作成します
  • 次に、更新されたデータを取得するためのメソッド(getData()として)、そして、兄弟コンポーネント間で共有されるカウント数を増やす、incrementData() メソッドを作成します。
  • そして、インクリメントボタンがクリックされるたびに更新された値を取得するためのsubject countを作成する 必要があります。

Subjectsは、変更があるたびに一貫して更新された値を提供する観測可能なものです。nextメソッドを呼び出して更新された値を取得することができます。

_以下のようにコードが書かれるはずです_

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class AppService {
  constructor() {}

  count = new Subject<number>();

  incrementData(count: number) {
    this.count.next(count);
  }

  getData() {
    return this.count;
  }
}
  • Firstコンポーネントでは、インクリメントボタンのクリックごとに呼び出されるメソッドを作成します。

覚えておくべき最初のステップは、サービスをコンストラクタ内で初期化し、後でそれを使ってサービスのメソッドにアクセスすることです

@Component({
  selector: 'my-first',
  template: `
    <h1>First</h1>
    <button (click)="incrementData()">Increment</button>
  `,
  standalone: true,
  imports: [CommonModule],
})
export class First {
  name = 'Angular';
  count: number = 0;

  constructor(private appService: AppService) {}

  incrementData() {
    this.appService.incrementData(this.count++);
  }
}
  • Secondコンポーネントでは、サービスで作成されたsubjectを購読して値を更新する必要があります。
@Component({
  selector: 'my-second',
  template: `
    <h1>Second</h1>
    <h2>{{count}}</h2>
  `,
  standalone: true,
  imports: [CommonModule],
})
export class Second {
  constructor(private appService: AppService) {
    this.appService.getData().subscribe((data) => {
      console.log(data);
      this.count = data;
    });
  }
  count: number = 0;

  name = 'Angular';
}

これがやり方です。

回答のフルコードはこちらです: https://stackblitz.com/edit/stackblitz-starters-gv2eui?file=src%2Fmain.ts

コメントで他の方法を教えてくれたら知りたいです。

読んでくれてありがとう。これがあなたの役に立ったら共有してください

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/deepachaurasia1/angular-interview-coding-question-1gok