27

私は AngularJS 2 サービスを作成し、それを 2 つの異なるコンポーネント (App-Component と Sub-Component) で使用しています。私のサービスの各出力プロパティ「ログ」(文字列)。

StateService クラス:

@Injectable ()
class StateService {

    public log : string;
    static count : number = 0;

    constructor () {
        this.log = '';
        StateService.count++;
        this.writeToLog ('CREATED '+StateService.count+' at ' + new Date().toString());
    }

    public writeToLog (text : string) : void {
        this.log += text + '\n';
    }
}  

成分 :

@Component ({
    selector : 'Sub-Component',
    template : `<hr>
            This is the Sub-Component !
            <BR>
            StateService Log : 
            <pre>{{ _stateService.log }}</pre>
            <button (click)="WriteToLog ()">Write to log</button>
            `,
    providers : [StateService]
})

export class SubComponent {
    constructor (private _stateService : StateService) {
    }

    public WriteToLog () : void {
        this._stateService.writeToLog ('From Sub-Component - This is '+new Date().toString());
    }
}

コードの実例はこちら

サービスが一度作成されることを除いて、各コンポーネントが WriteToLog メソッドを呼び出すと、出力は各コンポーネントで同じになりますが、そうではありません。

出力例:

App-Component はこれを出力できます:

インスタンス 1 - 2016 年 1 月 21 日木曜日 11:43:51 に作成

App-Component から - これは 2016 年 1 月 21 日木曜日 11:43:54 です

App-Component から - これは 2016 年 1 月 21 日木曜日 11:43:55 です

サブコンポーネントはこれを出力できます:

インスタンス 2 - 2016 年 1 月 21 日木曜日 11:43:51 に作成

サブコンポーネントから - これは 2016 年 1 月 21 日木曜日 11:43:57 です

サブコンポーネントから - これは 2016 年 1 月 21 日木曜日 11:43:58 です

そのため、サービスの 2 つのインスタンスが作成されたように見えます (インスタンス 1 + インスタンス 2)。

必要なインスタンスは 1 つだけです ;) ログに文字列を追加する場合、これは両方のコンポーネントに表示される必要があります。

ご協力ありがとうございました

4

2 に答える 2

32

角度を更新 >= 2.0.0-RC.6

コンポーネントのプロバイダーにサービスを追加しないでください。代わりに追加します

@NgModule({ providers: [...], ...

(遅延ロードされたモジュールが独自のスコープを導入するため、遅延ロードされていないモジュールの)

@Component ({
    selector : 'Sub-Component',
    template : `<hr>
            This is the Sub-Component !
            <BR>
            StateService Log : 
            <pre>{{ _stateService.log }}</pre>
            <button (click)="WriteToLog ()">Write to log</button>
            `,
    // providers : [StateService] <== remove
})

角度 <=2.0.0-RC.5

コンポーネントに追加すると、コンポーネント インスタンスごとに新しいサービス インスタンスが取得されます。代わりに追加します

bootstrap(AppComponent, [StateService]);

単一のコンポーネントに追加することで、よりきめ細かい制御を行うことができます。その後、このコンポーネントとすべての子に同じインスタンスが注入されますが、それ以外の場合、アプリケーションは によって作成されたインスタンスで動作しますbootstrap()。これは Angulars DI の「階層」です。

参照
- http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html
- http://blog.thoughtram.io/angular/2015/09/17 /resolve-service-dependencies-in-angular-2.html

于 2016-01-21T16:55:30.647 に答える
3

Günter の優れた回答に加えて、このリンクは、Angular2 の階層的な依存性注入がどのように機能するかについての詳細を提供する可能性があります。

于 2016-01-21T17:03:29.557 に答える