2017-03-02 9 views
0

他のコンポーネントから継承しているコンポーネントを作成しようとしていますが、子コンポーネントにコンストラクタパラメータを伝播する必要があるため、コードが非常に面倒になります。 次のコードを構成するより良い方法はありますか?Angular2 - extends components

基底クラスは次のとおりです。

import { alerts } from './alerts'; 
import { BaseFirebaseDaoService } from './../providers/base-firebase-dao-service'; 
import { Injectable,Component,Inject } from '@angular/core'; 
import { NavParams } from 'ionic-angular'; 
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; 
import { FirebaseListObservable } from 'angularfire2'; 

@Injectable() 
@Component({ 
    templateUrl: './dummy.html' 
}) 
export class BaseFormHandler<T extends BaseFirebaseDaoService> { 
    form: FormGroup; 
    item; 

    dao:T; 
    constructor(public navParams: NavParams, 
    public fb: FormBuilder, public _alerts:alerts) { 
    this.item = this.navParams.get("item");  
    this.buildForm(); 
    } 

    buildForm(){ 
    //to be ovveride in sub clusses. 
    } 

    remove(){  
    this.dao.remove(this.item.$key) 
    .then((a:void) => { 
     this._alerts.presentToast("removed success"); 
    }) 
    .catch((a:Error) => {this._alerts.presentToast("remove fail")}); 
    } 
    submit() { 
    let key = this.item.$key; 
    this.dao.update(key, this.form.value); 
    } 
} 

これは拡張クラスです:

import { alerts } from './../../shared/alerts'; 
import { BaseFormHandler } from './../../shared/base-form-handler'; 
import { Component } from '@angular/core'; 
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; 
import { MemberService } from '../../providers/member-service'; 
import { NavParams } from 'ionic-angular'; 
import { AngularFire } from 'angularfire2'; 

@Component({ 
    templateUrl: 'members-form-page.html' 
}) 
export class MembersFormPage extends BaseFormHandler<MemberService>{ 
    constructor(public navParams: NavParams, 
    public fb: FormBuilder, af: AngularFire, public _alerts: alerts) { 
    super(navParams, fb, _alerts); 
    this.dao = new MemberService(af); 
    } 
    buildForm() { 
    this.form = this.fb.group({ 
     name: [this.item.name, Validators.required], 
     email: [this.item.email, Validators.required] 
    }); 
    } 
} 

だから私は常にサブものの、すべてのサブクラスからpublic navParams: NavParams, public fb: FormBuilder, public _alerts:alertsコンストラクタのパラメータを送信(およびインポート)しなければなりませんそれらを使用していないクラス。このリストは長くなる可能性があります... そのような実装のための代替手段はありますか?あなたはまだこれを必要とする場合

+0

これを行う最良の方法ですが、別の選択肢がありますが、DI機能が失われます。サービスロケーター戦略を使用して、すべてを親に送信しないようにすることができます。 '@ angle/core'から' ReflectiveInjector'をチェックしてください。考え方は、基本コンポーネントに、使用したいサービスを見つけて返すようにすることです。 –

+0

親クラスのコンストラクタを呼び出す必要があり、すべてのパラメータも渡す必要があります。私がこのコードを少し短縮することを知っている唯一の方法は、子クラスのコンストラクタ内のアクセサ( 'public'、' protected'、 'private')をスキップすることです。 –

答えて

1

は分からないのですが、私は今日、同じ問題を抱えていたと私は、次の2つのリンクにいくつかの助けを見つけた:基本的に、私は」

Getting instance of service without constructor injection

https://github.com/angular/angular/issues/4112#issuecomment-153811572

すべての依存関係を解決するために "Base"クラスで使用するAngular Injectorを保持するグローバル変数を作成しました。このようにして、基本クラスを拡張する各Componentにそれらを挿入する必要はありません。

基本クラス:

export class BaseClass { 

    protected aService: AService; 
    protected bService: BService; 

    constructor() { 
     this.aService = appInjector().get(AService); 
     this.bService = appInjector().get(BService); 
    } 

    ... 

} 

AppInjectorの定義:私は(app.main.tsに私の場合には) "ルート" モジュールのブートストラップ後AppInjectorグローバルVARを初期化

import {Injector} from '@angular/core'; 

let appInjectorRef: Injector; 
export const appInjector = (injector?: Injector):Injector => { 
    if (injector) { 
     appInjectorRef = injector; 
    } 
    return appInjectorRef; 
}; 

platformBrowserDynamic().bootstrapModule(CpcAppModule) 
.then((modRef) => { 
    appInjector(modRef.injector); 
    console.log(`Application started`) 
}) 
.catch((err) => console.error(err)); 

希望します。