MetricsService
サービスを宣言するコンポーネントがあります。このサービスには、HttpModule
と、使用するホストおよび認証キーを定義する2つのstring
sの両方が必要です。
メトリックサービスは次のとおりです。
@Injectable()
export class MetricsService {
constructor(
private http: Http,
public wsAuthKey: string,
public wsHost: string
) {
this.wsAuthKey = wsAuthKey || "blahblahblahblahblahblahblahblah=";
this.wsHost = wsHost || "https://preprod-admin.myservice.ws";
}
それを使用するコンポーネントは次のように書かれています。
export class DatavizComponent implements OnInit, OnChanges {
constructor(
private zms: MetricsService,
) {
}
私の質問は、ホストとキーを渡すことを含む(ただし、httpは渡さない)全体が機能するように、コンポーネントコンストラクターをどのように記述するかです。
注:現在作成されているコードはコンパイルされません。
より正確には、コンポーネントがアプリ依存のデータを次のように提供することを期待します。
export class DatavizComponent implements OnInit, OnChanges {
constructor(
private zms = MetricsService("http://myhost.com", "mykey"),
) {
}
しかし、これが機能する場合、httpを渡す方法は?
提案されたソリューションの後の更新:
export class MetricsService {
constructor(
private http: Http,
@Inject('wsAuthKey') @Optional() public wsAuthKey?: string,
@Inject('wsHost') @Optional() public wsHost?: string
) {
this.wsAuthKey = wsAuthKey || "blahblah=";
this.wsHost = wsHost || "https://preprod-admin.Host.ws";
console.log("MetricsService constructor="
+ " wsAuthKey="+this.wsAuthKey
+ ", wsHost="+this.wsHost
);
}
コンポーネント内:
@Component({
selector: 'dataviz-offers-volumes',
templateUrl: 'app/dataviz.component.html',
styleUrls: ['app/dataviz.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [
{provide: 'wsAuthKey', useValue: 'abc'},
{provide: 'wsHost', useValue: 'efg'},
],
})
export class DatavizComponent implements OnInit, OnChanges {
@ViewChild('chart') private chartContainer: ElementRef;
@Input() private graphId:string;
@Input() private wsAuthKey:string;
@Input() private wsHost:string;
@Input() private maxSamples=12;
constructor(
private zms: MetricsService
) {
}
コンストラクターでは、ログは次のとおりです(値は渡されません)。
MetricsService constructor= wsAuthKey=blahblah=, wsHost=https://preprod-admin.Host.ws
「abc」と「efg」が表示されるはずです。
しかし、dataviz componenetを使用するコンポーネントに問題はないのでしょうか。このコンポーネントでは、次の情報が渡されました。
@Input() private wsAuthKey:string;
@Input() private wsHost:string;
タグでオプションでホストとキーをプリセットしたいので:
<h1>dataviz volume</h1>
<div class="chartContainer left" title="Simultaneous offers via dataviz directive">
<dataviz-offers-volumes
id="dataviz-volumes1"
[graphId]="graphId"
[wsAuthKey]="'myauthkey'"
[wsHost]="'http://myhost.com'"
[maxSamples]="123"
>
</dataviz-offers-volumes>
</div>
パラメーターをオプションにするには、@Optional()
(DI)および_?
_(TypeScript)、およびプロバイダーキーとしてサポートされていないプリミティブ値の@Inject(somekey)
を追加します。
_@Injectable()
export class MetricsService {
constructor(
private http: Http,
@Inject('wsAuthKey') @Optional() public wsAuthKey?: string,
@Inject('wsHost') @Optional() public wsHost?: string
) {
this.wsAuthKey = wsAuthKey || "blahblahblahblahblahblahblahblah=";
this.wsHost = wsHost || "https://preprod-admin.myservice.ws";
}
_
_providers: [
{provide: 'wsAuthKey', useValue: 'abc'},
{provide: 'wsHost', useValue: 'efg'},
]
_
指定された場合は渡され、そうでない場合は無視されますが、DIは依然としてMetricsService
を挿入できます。
これは、特に この質問 で説明されている一般的なレシピです。設定を保持するサービスである必要があります。
@Injectable()
export class MetricsConfig {
wsAuthKey = "blahblahblahblahblahblahblahblah=";
wsHost = "https://preprod-admin.myservice.ws";
}
@Injectable()
export class MetricsService {
constructor(
private http: Http,
metricsConfig: MetricsConfig
) {
this.wsAuthKey = metricsConfig.wsAuthKey;
this.wsHost = metricsConfig.wsHost;
}
}
変更する必要がある場合は、モジュール全体または特定のコンポーネントに対してオーバーライドまたは拡張できます。
@Component(
...
{ provide: MetricsConfig, useClass: class ExtendedMetricsConfig { ... } }
)
export class DatavizComponent ...
この場合、MetricsConfig
をクラスにする必要はありません。 OpaqueToken値プロバイダーでもあります。しかし、クラスは便利に拡張することができ、注入するのが簡単で、すでに入力用のインターフェースを提供しています。
公式ドキュメントから: https://angular.io/guide/dependency-injection-in-action#injectiontoken
コンストラクターで@Optional
デコレーターを使用します。
export class MyService {
constructor( @Optional() public var: type = value ) { }
}