问题
I am currently trying to send data between components via a data service using "BehaviorSubject". In the first component, I am updating the messageSoruce and in the second component , retrieving the data but it is empty. I checked that the value "this.card.img" is not empty. What am I missing ?
Data Service
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject("")
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
First component
import {Component} from '@angular/core';
import {Router} from '@angular/router';
import {DataService} from 'src/app/services/data/data.service';
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
providers: [ DataService ],
styleUrls: ['./card.component.css']
})
export class CardComponent {
@Input('card') card:Card
constructor(public router: Router,
public dataService :DataService ) {
}
openDetails() {
this.dataService.changeMessage(this.card.img)
this.router.navigateByUrl('/imganalyse');
}
}
Second component
import { Component, OnInit, } from '@angular/core';
import {DataService} from '../../services/data/data.service'
@Component({
selector: 'app-imganalyse',
templateUrl: './imganalyse.component.html',
providers: [ DataService ],
styleUrls: ['./imganalyse.component.css']
})
export class ImganalyseComponent implements OnInit {
channel: string;
constructor(private youtubeService:YoutubeService,
private dataService:DataService) {
}
ngOnInit() {
this.dataService.currentMessage.subscribe(channel => this.channel = channel)
console.log(this.channel)
}
}
回答1:
Solution:
The providers: [DataServie] needs only to be set in app.module.ts to only use one instance. In my case every component had his own dataservice provider , therefore it had more than one instance ...(that's the reason why it was always empty)
回答2:
First, when you declare DataService
in the component providers, it creates a new instance. This means that FirstComponent.dataService
refers to a different object than SecondComponent.dataService
. Remove the 'providers' property from your component decorators and add 'providedIn' to your DataService decorator to make it a singleton so all references will refer to the same instance (unless you put it in a class's 'providers'):
@Injectable({
providedIn: 'root'
})
export class DataService {
You are logging outside the subscription. When you call this:
this.dataService.changeMessage(this.card.img)
In your second component you have this in the OnInit:
this.dataService.currentMessage.subscribe(channel => this.channel = channel)
console.log(this.channel)
So you subscribe and do nothing but set the channel when it is changed, but your log happens immediately, so this.channel
will not be set yet. I don't know what is calling openDetails()
, but try this in your second component:
this.dataService.currentMessage.subscribe(channel => {
this.channel = channel;
console.log('updated channel:', channel);
});
来源:https://stackoverflow.com/questions/54726860/sharing-data-between-components-angular-7