angular - Angular2-komponenter misslyckas med att kommunicera via observable i en tjänst


Jag försöker få komponenter att skicka meddelanden via en delad tjänst, som i en kokboks recept "Förälder och barn kommunicerar via en tjänst". Jag har en Sender-komponent som kallar på en tjänsts metod, där en händelse utlöses. Och det finns en Receiver-komponent, som bara lyssnar på händelser.

Problemet är att Receiver inte får någon händelse. Här är koden:

import {bootstrap} from 'angular2/platform/browser'
import {Injectable, Component} from 'angular2/core';

import 'rxjs/Rx';
import {Subject}    from 'rxjs/Subject';

@Injectable()
export class TestService {
    private _subject = new Subject<any>();
    event$ = this._subject.asObservable();

    doFoo() {
        console.log('Doing foo hard...')
        this._subject.next('hey');
    }
}

@Component({
    selector: 'receiver-component',
    template: 'Value is {{ value }}',
    providers: [
        TestService
    ],
})
export class ReceiverComponent {
    private value: number = 'nope';

    constructor(private service: TestService) {
        this.service.event$.subscribe(data => this.value = data)
    }
}

@Component({
    selector: 'sender-component',
    template: '<button (click)="fireEvent()">Click me</button>',
    providers: [
        TestService
    ],
})
export class SenderComponent {
    constructor (private service: TestService) {}

    fireEvent() {
        this.service.doFoo()
    }
}

bootstrap(SenderComponent);
bootstrap(ReceiverComponent);

När jag klickar på knappen ser jag felsökningsmeddelandet från TestService.doFoo(), så det körs. Men evenemangsmeddelandet förs bara inte vidare. Varför?

Uppdatering: Jag använder [email  och [email .

Svar #1

Detta är inte en delad tjänst. Varje komponent får sin egen instans.

Om du lägger till tjänsten i providers-listan för komponenten, kommer varje komponent att få en ny instans.

Om du kör bootstrap() två gånger skapar du två olika Angular-applikationer som inte delar någonting. Se de sista raderna i koden för hur du ändå etablerar anslutningen:

import {bootstrap} from 'angular2/platform/browser'
import {Injectable, Component, provide} from 'angular2/core';

import 'rxjs/Rx';
import {Subject}    from 'rxjs/Subject';

@Injectable()
export class TestService {
    private _subject = new Subject<any>();
    event$ = this._subject.asObservable();

    doFoo() {
        console.log('Doing foo hard...')
        this._subject.next('hey');
    }
}

@Component({
    selector: 'receiver-component',
    template: 'Value is {{ value }}',
//    providers: [
//        TestService
//    ],
})
export class ReceiverComponent {
    private value: number = 'nope';

    constructor(private service: TestService) {
        this.service.event$.subscribe(data => this.value = data)
    }
}

@Component({
    selector: 'sender-component',
    template: '<button (click)="fireEvent()">Click me</button>',
//    providers: [
//        TestService
//    ],
})
export class SenderComponent {
    constructor (private service: TestService) {}

    fireEvent() {
        this.service.doFoo()
    }
}

sharedService = new TestService();
bootstrap(SenderComponent, [provide(TestService, {useValue: sharedService})]);
bootstrap(ReceiverComponent, [provide(TestService, {useValue: sharedService})]);