在组件之间共享数据 (Angular 7)
Sharing Data between Components (Angular 7)
我目前正在尝试使用 "BehaviorSubject" 通过数据服务在组件之间发送数据。在第一个组件中,我正在更新 messageSoruce,在第二个组件中,我正在检索数据,但它是空的。我检查了值 "this.card.img" 不为空。我错过了什么?
数据服务
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)
}
}
第一部分
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');
}
}
第二部分
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)
}
}
解决方案:
供应商:[DataServie]只需要在app.module.ts中设置为只使用一个实例。在我的例子中,每个组件都有自己的数据服务提供者,因此它有多个实例......(这就是为什么它总是空的原因)
首先,当您在组件提供程序中声明 DataService
时,它会创建一个新实例。这意味着 FirstComponent.dataService
与 SecondComponent.dataService
指的是不同的对象。从您的组件装饰器中删除 'providers' 属性 并将 'providedIn' 添加到您的 DataService 装饰器以使其成为单例,因此所有引用都将引用同一实例(除非您将其放在 class的'providers'):
@Injectable({
providedIn: 'root'
})
export class DataService {
您正在订阅之外登录。当你这样称呼时:
this.dataService.changeMessage(this.card.img)
在您的第二个组件中,您在 OnInit 中有这个:
this.dataService.currentMessage.subscribe(channel => this.channel = channel)
console.log(this.channel)
因此您订阅并在频道更改时除了设置频道外什么都不做,但是您的日志会立即发生,因此 this.channel
还不会设置。我不知道什么叫 openDetails()
,但在你的第二个组件中试试这个:
this.dataService.currentMessage.subscribe(channel => {
this.channel = channel;
console.log('updated channel:', channel);
});
我目前正在尝试使用 "BehaviorSubject" 通过数据服务在组件之间发送数据。在第一个组件中,我正在更新 messageSoruce,在第二个组件中,我正在检索数据,但它是空的。我检查了值 "this.card.img" 不为空。我错过了什么?
数据服务
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)
}
}
第一部分
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');
}
}
第二部分
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)
}
}
解决方案:
供应商:[DataServie]只需要在app.module.ts中设置为只使用一个实例。在我的例子中,每个组件都有自己的数据服务提供者,因此它有多个实例......(这就是为什么它总是空的原因)
首先,当您在组件提供程序中声明 DataService
时,它会创建一个新实例。这意味着 FirstComponent.dataService
与 SecondComponent.dataService
指的是不同的对象。从您的组件装饰器中删除 'providers' 属性 并将 'providedIn' 添加到您的 DataService 装饰器以使其成为单例,因此所有引用都将引用同一实例(除非您将其放在 class的'providers'):
@Injectable({
providedIn: 'root'
})
export class DataService {
您正在订阅之外登录。当你这样称呼时:
this.dataService.changeMessage(this.card.img)
在您的第二个组件中,您在 OnInit 中有这个:
this.dataService.currentMessage.subscribe(channel => this.channel = channel)
console.log(this.channel)
因此您订阅并在频道更改时除了设置频道外什么都不做,但是您的日志会立即发生,因此 this.channel
还不会设置。我不知道什么叫 openDetails()
,但在你的第二个组件中试试这个:
this.dataService.currentMessage.subscribe(channel => {
this.channel = channel;
console.log('updated channel:', channel);
});