Обмен данными между компонентами (Angular 7)

В настоящее время я пытаюсь отправить данные между компонентами через службу данных, используя «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.channe вместо this.channel?

Zachary Bennett 17.02.2019 05:45

при копировании и вставке ошибся, значение это this.channel

Eltomon 17.02.2019 11:35

Есть ли способ создать блиц стека или вставить HTML-шаблоны. Я скажу одну вещь, чисто стилистически соглашение Angular при работе с Observables заключается в том, чтобы имена переменных заканчивались знаком $. Итак, в вашем DataService currentMessage должно быть currentMessage$, если вам/вашей организации это не важно.

Zachary Bennett 17.02.2019 13:38

Поставщики: [DataServie] нужно только установить в app.module.ts, чтобы использовать только один экземпляр.

Eltomon 18.02.2019 22:55
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
4
4
3 819
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Решение:

Поставщики: [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?

roberto tomás 23.04.2019 00:58

Поместите службу в провайдеров в свой основной модуль и больше нигде, и у вас должен быть только один экземпляр.

Jason Goemaat 24.04.2019 19:37

Другие вопросы по теме