Совместное использование данных между компонентами (Angular 7) - PullRequest
0 голосов
/ 16 февраля 2019

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

  }

}

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Во-первых, когда вы объявляете DataService в поставщиках компонентов, он создает новый экземпляр.Это означает, что FirstComponent.dataService относится к объекту, отличному от SecondComponent.dataService.Удалите свойство «provider» из ваших декораторов компонентов и добавьте «provideIn» в ваш декоратор DataService, чтобы сделать его одноэлементным, чтобы все ссылки ссылались на один и тот же экземпляр (если вы не поместили его в «поставщики» класса):

@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);
});



0 голосов
/ 17 апреля 2019

Решение:

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

...