Angular で動的に作成されたコンポーネントを使用している場合、必要なときに親コンポーネントと子コンポーネントの間で情報を渡すのが難しいことに気付いたことがあるでしょう。親で情報を提供し、それを子コンポーネント内に挿入する必要があります。これは必ずしも難しいことではありませんが、多くの余分な定型コードが必要になります。
これまでと同じように@Input
デコレータを使用できれば、さらに良いでしょう。さて、どうでしょうか? Angular はバージョン 16 の時点でこれとまったく同じことをサポートしています。この投稿ではその方法を説明します。さて、それでは始めましょう。
まず、動的に作成されたコンポーネントに親からデータを渡す方法を見てみましょう。この例では、コンポーネント テンプレート内に*ngComponentOutlet
があり、それをプレーヤー コンポーネントに渡しています。
この場合、カスタムの子インジェクターも渡しており、以前はこのようにして子コンポーネントにデータを注入していました。
@Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; injector: childInjector"></ng-container> ` }) export class App { protected playerComponent = PlayerComponent; }
この子インジェクターを作成するには、テンプレート内で設定して使用できるようにプロパティを作成する必要がありました。
export class App { protected childInjector?: Injector; ... }
次に、コンストラクター内の angular コアからインジェクターに注入する必要がありました。
export class App { ... constructor(private injector: Injector) { } }
その後、create メソッドとプロバイダーの配列を使用して子インジェクターを設定し、プレーヤー トークンを子に提供する必要がありました。
export class App { ... constructor(private injector: Injector) { this.childInjector = Injector.create({ providers: [ { provide: PlayerToken, useValue: this.player } ], parent: this.injector }); } }
最後に、子コンポーネントであるプレーヤー コンポーネントで、Angular コアからの inject メソッドを使用してプレーヤー プロパティを設定する必要がありました。
export class PlayerComponent { protected player?: Player = inject(PlayerToken); }
したがって、これはすべて、単純なプレーヤー オブジェクトを動的コンポーネントに渡すだけです。つまり、これが動的コンポーネントでない場合は、これを@Input
にして、プレーヤー データ オブジェクトを親の@Input
にバインドするだけです。しかし、これは動的に作成されたコンポーネントなので、これを行うことはできませんよね?
さて、Angular 16 の時点では、実際には代わりに@Input
を使用でき、これまで見てきたものよりもはるかに単純です。
*ngComponentOutlet
入力オブジェクトを使用した新しい方法でデータを渡すまず、このプレーヤー プロパティを@Input
に変更します。そして、それはプレーヤー インターフェイスに入力されるだけです。
export class PlayerComponent { @Input() player?: Player; }
ここで、inject メソッドとプレーヤー トークンのインポートは不要になったので、削除できます。次に、親のテンプレートに戻り、インジェクターを削除し、代わりに入力オブジェクトに置き換えます。このオブジェクトを任意の数の入力に渡すことができます。したがって、入力が 5 つある場合は、それらの名前を含めるだけで、必要なデータをそれぞれに渡すことになります。
ただし、この場合、子コンポーネント player には入力が 1 つしかないため、それを渡す必要があるのはそれだけです。
@Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; inputs: { player }"></ng-container> ` })
これで、子インジェクターを削除できます。これは、コンストラクターを完全に削除することもできることを意味します。最後に、Angular コアとプレーヤー トークンのインポートからインジェクターを削除できます。これらは使用されなくなったためです。
export class App { protected player: Player = { name: 'LeBron James', games: 1421, points: 38652, fieldGoalPercentage: 0.505, threePointPercentage: 0.345, imageName: 'lebron-james' }; protected playerComponent = PlayerComponent; }
以上です。すべてが以前と同じように機能していることがわかります。したがって、実行がかなり簡単になり、コードも少なくなり、常に素晴らしいことになります。
ただし、残念な点は、 @Input
はサポートされているものの、 @Output
はサポートされていないことです。ちょっと残念ですが、それが現実です。これも非常に便利なので、将来的にサポートが追加されることを願っていますが、私たちは待つしかありません。
以下の Stackblitz の例で、デモ コードとこれらのテクニックの例を確認してください。ご質問やご意見がございましたら、お気軽にコメントを残してください。