В настоящее время я пытаюсь отправить данные между компонентами через службу данных, используя «BehaviorSubject». В первом компоненте я обновляю источник сообщений, а во втором компоненте извлекаю данные, но он пуст. Проверил, что значение "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.info(this.channel)
}
}
при копировании и вставке ошибся, значение это this.channel
Есть ли способ создать блиц стека или вставить HTML-шаблоны. Я скажу одну вещь, чисто стилистически соглашение Angular при работе с Observables заключается в том, чтобы имена переменных заканчивались знаком $. Итак, в вашем DataService currentMessage должно быть currentMessage$, если вам/вашей организации это не важно.
Поставщики: [DataServie] нужно только установить в app.module.ts, чтобы использовать только один экземпляр.





Решение:
Поставщики: [DataServie] нужно только установить в app.module.ts, чтобы использовать только один экземпляр. В моем случае у каждого компонента был свой поставщик услуг данных, поэтому у него было более одного экземпляра... (поэтому он всегда был пуст)
Во-первых, когда вы объявляете DataService в поставщиках компонентов, создается новый экземпляр. Это означает, что FirstComponent.dataService относится к другому объекту, чем SecondComponent.dataService. Удалите свойство «поставщики» из ваших декораторов компонентов и добавьте «providedIn» в ваш декоратор DataService, чтобы сделать его одноэлементным, чтобы все ссылки относились к одному и тому же экземпляру (если вы не поместите его в «поставщики» класса):
@Injectable({
providedIn: 'root'
})
export class DataService {
Вы входите вне подписки. Когда вы вызываете это:
this.dataService.changeMessage(this.card.img)
Во втором компоненте у вас есть это в OnInit:
this.dataService.currentMessage.subscribe(channel => this.channel = channel)
console.info(this.channel)
То есть вы подписываетесь и ничего не делаете, кроме как устанавливаете канал при его изменении, но ваш лог происходит сразу, поэтому this.channel пока не будет установлен. Я не знаю, что вызывает openDetails(), но попробуйте это во втором компоненте:
this.dataService.currentMessage.subscribe(channel => {
this.channel = channel;
console.info('updated channel:', channel);
});
это как угловой 6+ правильно? как вы это делаете с angular 5?
Поместите службу в провайдеров в свой основной модуль и больше нигде, и у вас должен быть только один экземпляр.
Вы поняли, что во втором компоненте вы пытаетесь установить
this.channeвместоthis.channel?