【Angular2】コンポーネント間でデータを受け渡し:InputとOutput編
Angular 2 コンポーネントに文字列値を渡す方法
@Input デコレータ
@Input デコレータは、コンポーネントのプロパティを外部から設定できるようにするものです。以下の例のように、コンポーネントのクラスに @Input デコレータを定義し、プロパティ名を指定します。
import { Component, Input } from '@angular/core';
@Component({
selector: 'my-component',
template: '<p>コンポーネントに渡された文字列: {{ message }}</p>',
})
export class MyComponent {
@Input() message: string;
}
上記のように定義したコンポーネントをテンプレートで使用する場合、以下の例のように message
プロパティに文字列値をバインドします。
<my-component [message]="'Hello, Angular2!'"></my-component>
コンポーネント入力プロパティのバインディング
コンポーネント入力プロパティのバインディングは、属性構文を使用して行うことができます。以下の例のように、コンポーネントの要素に message
属性を設定し、その値をバインドします。
<my-component message="Hello, Angular2!"></my-component>
双方向バインディング
双方向バインディングを使用すると、コンポーネントのプロパティ値とテンプレートの値を相互に同期することができます。双方向バインディングを行うには、ngModel
ディレクティブを使用します。以下の例のように、ngModel
ディレクティブをコンポーネントの要素に設定し、[(ngModel)]
バインディングを使用します。
<input type="text" [(ngModel)]="message">
<my-component [message]="message"></my-component>
上記のように、Angular 2 コンポーネントに文字列値を渡すには、主に @Input デコレータ、コンポーネント入力プロパティのバインディング、双方向バインディングの 3 つの方法があります。状況に応じて適切な方法を選択してください。
- 双方向バインディングを使用する場合は、コンポーネントのクラスで
EventEmitter
を使用してイベントを発行し、テンプレートでイベントを処理する必要があります。 - コンポーネントに渡す値は、コンポーネントのクラスのプロパティ型と一致する必要があります。
<div>
<h2>親コンポーネント</h2>
<input type="text" [(ngModel)]="message">
<my-component [message]="message"></my-component>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
message = 'Hello, Angular2!';
}
<p>コンポーネントに渡された文字列: {{ message }}</p>
import { Component, Input } from '@angular/core';
@Component({
selector: 'my-component',
template: './my-component.html',
})
export class MyComponent {
@Input() message: string;
}
<div>
<h2>親コンポーネント</h2>
<my-component message="Hello, Angular2!"></my-component>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}
<p>コンポーネントに渡された文字列: {{ message }}</p>
import { Component, Input } from '@angular/core';
@Component({
selector: 'my-component',
template: './my-component.html',
})
export class MyComponent {
@Input() message: string;
}
<div>
<h2>親コンポーネント</h2>
<input type="text" [(ngModel)]="message">
<my-component [message]="message"></my-component>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
message = 'Hello, Angular2!';
}
<p>コンポーネントに渡された文字列: {{ message }}</p>
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'my-component',
template: './my-component.html',
})
export class MyComponent {
@Input() message: string;
@Output() messageChange = new EventEmitter<string>();
onChange(newMessage: string) {
this.message = newMessage;
this.messageChange.emit(newMessage);
}
}
サービスを利用して、コンポーネント間でデータを共有する方法があります。以下の例のように、サービスで文字列値を保持し、コンポーネントはその値を注入して利用します。
app.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AppService {
message = 'Hello, Angular2!';
}
<div>
<h2>親コンポーネント</h2>
<input type="text" [(ngModel)]="message">
<my-component [message]="message"></my-component>
</div>
import { Component, Inject } from '@angular/core';
import { AppService } from './app.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
message: string;
constructor(@Inject(AppService) private appService: AppService) {
this.message = appService.message;
}
}
<p>コンポーネントに渡された文字列: {{ message }}</p>
import { Component, Input } from '@angular/core';
import { AppService } from './app.service';
@Component({
selector: 'my-component',
template: './my-component.html',
})
export class MyComponent {
@Input() message: string;
constructor(@Inject(AppService) private appService: AppService) {}
}
ルーターを利用する
ルーターを利用して、コンポーネント間でデータを共有する方法があります。以下の例のように、ActivatedRoute
サービスを使用して、ルートパラメータから文字列値を取得します。
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'my-component/:message', component: MyComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
<div>
<h2>親コンポーネント</h2>
<a routerLink="/my-component/Hello, Angular2!">My Component に移動</a>
</div>
<p>コンポーネントに渡された文字列: {{ message }}</p>
import { Component, ActivatedRoute } from '@angular/core';
@Component({
selector: 'my-component',
template: './my-component.html',
})
export class MyComponent {
message: string;
constructor(private activatedRoute: ActivatedRoute) {
this.message = activatedRoute.snapshot.params['message'];
}
}
ローカルストレージを利用する
ローカルストレージを利用して、コンポーネント間でデータを共有する方法があります。以下の例のように、localStorage
APIを使用して、文字列値を保存および取得します。
<div>
<h2>親コンポーネント</h2>
<input type="text" [(ngModel)]="message">
<button (click)="saveMessage()">メッセージを保存</button>
<a routerLink="/my-component">My Component に移動</a>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
message: string;
saveMessage() {
localStorage.setItem('message', this.message);
}
}
angular angular2-template