Angular ViewProviders と Providers を使いこなしてコードをスッキリさせよう
AngularにおけるViewProvidersとProvidersの違い
適用範囲
- Providers: コンポーネント自身とそのすべての子コンポーネントにサービスを提供します。
- ViewProviders: コンポーネントとその直接の子コンポーネントにのみサービスを提供します。投影されたコンテンツには提供されません。
使用例
- Providers: コンポーネント全体で共有されるサービスを提供するために使用します。
メリットとデメリット
-
Providers:
- メリット:
- デメリット:
- テンプレートコードが複雑になる
- メリット:
-
- メリット:
- サービスのスコープをより細かく制御できる
- テンプレートコードをよりシンプルに保つことができる
- デメリット:
- メリット:
まとめ
補足
- 投影されたコンテンツとは、別のコンポーネントのテンプレートから現在のコンポーネントのテンプレートに挿入されたコンテンツです。
- メモリ使用量は、アプリケーションが実行中に使用するメモリの量です。
例
// Providers
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MyService]
})
export class AppComponent {
constructor(private myService: MyService) {}
}
// ViewProviders
@Component({
selector: 'my-component',
templateUrl: './my-component.html',
styleUrls: ['./my-component.css'],
viewProviders: [MyService]
})
export class MyComponent {
constructor(private myService: MyService) {}
}
この例では、MyService
はAppComponent
とそのすべての子コンポーネントに提供されます。一方、MyComponent
では、MyService
はMyComponent
とその直接の子コンポーネントにのみ提供されます。
// サービス
export class MyService {
constructor() {}
}
// コンポーネント
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MyService]
})
export class AppComponent {
constructor(private myService: MyService) {}
}
@Component({
selector: 'child-component',
templateUrl: './child-component.html',
styleUrls: ['./child-component.css']
})
export class ChildComponent {
constructor(private myService: MyService) {}
}
この例では、MyService
はAppComponent
とその子コンポーネントであるChildComponent
に提供されます。
// サービス
export class MyService {
constructor() {}
}
// コンポーネント
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private myService: MyService) {}
}
@Component({
selector: 'my-component',
templateUrl: './my-component.html',
styleUrls: ['./my-component.css'],
viewProviders: [MyService]
})
export class MyComponent {
constructor(private myService: MyService) {}
}
@Component({
selector: 'child-component',
templateUrl: './child-component.html',
styleUrls: ['./child-component.css']
})
export class ChildComponent {
constructor(private myService: MyService) {}
}
この例では、MyService
はMyComponent
とその直接の子コンポーネントであるChildComponent
にのみ提供されます。MyComponent
の親コンポーネントであるAppComponent
はMyService
にアクセスできません。
実行
上記のコードをng serve
コマンドで実行すると、ブラウザでアプリケーションが起動します。
確認
ブラウザでアプリケーションを開き、コンポーネントのテンプレートコードを確認します。
- 例1:
- 例2:
Angularでサービスを提供する他の方法
ファクトリー関数は、サービスのインスタンスを作成するために使用できます。
export function myServiceFactory() {
return new MyService();
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [
{
provide: MyService,
useFactory: myServiceFactory
}
]
})
export class AppComponent {
constructor(private myService: MyService) {}
}
値プロバイダは、サービスのインスタンスではなく、直接値を提供するために使用できます。
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [
{
provide: 'myValue',
useValue: 'Hello, world!'
}
]
})
export class AppComponent {
constructor(@Inject('myValue') private myValue: string) {}
}
@Injectable()
export class MyService {
constructor() {}
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [MyService]
})
export class AppComponent {
constructor(private myService: MyService) {}
}
モジュールプロバイダは、モジュール全体でサービスを提供するために使用できます。
@NgModule({
imports: [],
declarations: [
AppComponent
],
providers: [MyService],
bootstrap: [AppComponent]
})
export class AppModule {}
エイリアスを使用して、サービスの別の名前を提供できます。
@Injectable()
export class MyService {
constructor() {}
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [
{
provide: MyService,
useClass: MyService
},
{
provide: 'MyAlias',
useExisting: MyService
}
]
})
export class AppComponent {
constructor(private myService: MyService, @Inject('MyAlias') private myAlias: MyService) {}
}
Angularでは、サービスを提供する様々な方法があります。それぞれの方法には、メリットとデメリットがあります。サービスのスコープ、コードの簡潔さ、パフォーマンスなどを考慮して、どの方法を使用するかを決める必要があります。
angular