Angular2における子コンポーネントから親コンポーネントへのアクセス方法:その他の方法
Angular2における子コンポーネントから親コンポーネントの変数・関数へのアクセス方法
Inputプロパティは、親コンポーネントから子コンポーネントへデータを一方通行で渡すためのものです。親コンポーネントのテンプレートで子コンポーネントを呼び出す際に、[]
で囲んだ値を子コンポーネントのInputプロパティにバインドします。
例
親コンポーネント(parent.component.ts
)
export class ParentComponent {
message = 'こんにちは!';
}
<child-component [message]="message"></child-component>
export class ChildComponent {
@Input() message: string;
}
<p>{{ message }}</p>
上記の例では、親コンポーネントの message
変数が子コンポーネントの message
Inputプロパティにバインドされています。子コンポーネントは、message
Inputプロパティを通じて親コンポーネントの message
変数にアクセス and 値を変更することができます。
@ViewChildデコレータは、親コンポーネントから子コンポーネントのインスタンスを直接取得するためのものです。取得したインスタンスを通じて、子コンポーネントの変数や関数にアクセスすることができます。
export class ParentComponent {
@ViewChild('child') child: ChildComponent;
changeMessage() {
this.child.message = 'Angular はすごい!';
}
}
<child-component #child></child-component>
export class ChildComponent {
message = 'Angular を学ぼう!';
}
上記の例では、親コンポーネントのテンプレートで #child
というローカル変数を使って子コンポーネントに名前を付け、@ViewChild
デコレータでその子コンポーネントのインスタンスを child
変数に取得しています。親コンポーネントの changeMessage
メソッドでは、child
変数を通じて子コンポーネントの message
変数にアクセス and 値を変更しています。
補足
- Inputプロパティと @ViewChildデコレータは、それぞれ異なるユースケースに適しています。
- Inputプロパティは、親コンポーネントから子コンポーネントへデータを一方通行で渡す場合に適しています。
- @ViewChildデコレータは、子コンポーネントのインスタンスを直接操作したい場合や、子コンポーネントのメソッドを呼び出す場合に適しています。
- 上記以外にも、イベントバインディングやサービスを利用した方法で子コンポーネントから親コンポーネントにアクセスすることも可能です。
サンプルコード:Angular2における子コンポーネントから親コンポーネントへのアクセス
Inputプロパティを使用した例
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
message = 'こんにちは!';
constructor() { }
ngOnInit(): void { }
changeMessage() {
this.message = 'Angular はすごい!';
}
}
<child-component [message]="message" (messageChanged)="onMessageChanged($event)"></child-component>
<button (click)="changeMessage()">メッセージを変更</button>
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@Input() message: string;
@Output() messageChanged = new EventEmitter<string>();
changeMessage() {
this.messageChanged.emit('Angular を学ぼう!');
}
}
<p>{{ message }}</p>
<button (click)="changeMessage()">メッセージを変更</button>
@ViewChildデコレータを使用した例
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
@ViewChild('child') child: ChildComponent;
constructor() { }
ngOnInit(): void { }
changeMessage() {
this.child.message = 'Angular はすごい!';
}
}
<child-component #child></child-component>
<button (click)="changeMessage()">メッセージを変更</button>
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
message = 'Angular を学ぼう!';
@Output() messageChanged = new EventEmitter<string>();
changeMessage() {
this.messageChanged.emit('Angular を学ぼう!');
}
}
<p>{{ message }}</p>
<button (click)="changeMessage()">メッセージを変更</button>
説明
- 親コンポーネントの
message
変数は、子コンポーネントのmessage
Inputプロパティにバインドされています。 - 親コンポーネントの
changeMessage
メソッドは、message
変数を変更し、子コンポーネントに反映します。 - 親コンポーネントのテンプレートで
(messageChanged)
イベントハンドラを定義し、イベントを受け取った際に処理を実行します。
- 親コンポーネントの
@ViewChild
デコレータで、子コンポーネントのインスタンスをchild
変数に取得します。
Angular2における子コンポーネントから親コンポーネントへのアクセス方法:その他の方法
イベントバインディングは、子コンポーネントから親コンポーネントへイベントを発信し、親コンポーネントでイベントを受け取って処理する方法です。
利点
- 子コンポーネントと親コンポーネントのコードを分離できる
- 双方向の通信が可能
欠点
- イベントハンドラを定義する必要がある
- 複雑なロジックの場合、コードが冗長になる可能性がある
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
message = 'こんにちは!';
constructor() { }
ngOnInit(): void { }
onMessageChanged(message: string) {
this.message = message;
}
}
<child-component (messageChanged)="onMessageChanged($event)"></child-component>
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@Input() message: string;
@Output() messageChanged = new EventEmitter<string>();
changeMessage() {
this.messageChanged.emit('Angular を学ぼう!');
}
}
<p>{{ message }}</p>
<button (click)="changeMessage()">メッセージを変更</button>
サービスは、コンポーネント間でデータを共有するための方法です。子コンポーネントはサービスにデータを登録し、親コンポーネントはサービスからデータを取得することができます。
- データをコンポーネント間で共有しやすい
- テストしやすい
- サービスを定義する必要がある
サービス(message.service.ts)
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MessageService {
private message: string = 'こんにちは!';
getMessage(): string {
return this.message;
}
setMessage(message: string) {
this.message = message;
}
}
import { Component, OnInit, Inject } from '@angular/core';
import { MessageService } from './message.service';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
message: string;
constructor(@Inject(MessageService) private messageService: MessageService) { }
ngOnInit(): void {
this.message = this.messageService.getMessage();
}
changeMessage() {
this.messageService.setMessage('Angular はすごい!');
}
}
<child-component [message]="message"></child-component>
<button (click)="changeMessage()">メッセージを変更</button>
import { Component, Input, Inject } from '@angular/core';
import { MessageService } from './message.service';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.
angular