ПоведениеSubject не будет обновляться по другому маршруту - PullRequest
0 голосов
/ 23 апреля 2020

Я довольно новичок в Angular, и у меня возникают проблемы при передаче массива в другой (не связанный с родителем / дочерним) компонент по другому маршруту . В моем приложении нужно нажать кнопку, чтобы пометить бронирование как «принятое», и отобразить тот же массив принятых заказов в другом представлении (изменение маршрута).

Я пробовал реализует BehaviorSubject, но он не работает. Я могу установить массив успешно, но когда я хочу получить его, подписавшись на него во 2-м компоненте, он показывает только начальное значение субъекта, которое в данном случае - «Hello World». Пожалуйста, помогите мне, я пробовал это в течение недели, смотрел видео на YouTube и гуглил, но я не могу найти, что не так. PD: я не добавил sharedService в качестве провайдера в app.component.ts, если кому-то было интересно.

First component
import { Component, OnInit } from '@angular/core';
import {SharedService} from '../../services/shared.service';
import {share} from 'rxjs/operators';

@Component({
  selector: 'app-turnos',
  templateUrl: './turnos.component.html',
  styleUrls: ['./turnos.component.css'],
  providers:[TurnoService]
})
export class TurnosComponent implements OnInit {

    public turnos: Turno;
    public status;


  constructor(

    private _sharedService: SharedService

    ) { }


  acceptBooking(booking){

    this._sharedService.addToAccepted(booking);

    this._sharedService.acceptedBookingsSubject.pipe(share()).subscribe(res=>console.log(res));
//this is just to watch the response, which shows the correct array, but it works only in this component
}

}

Теперь общая служба

import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {Turno} from '../models/turno';
import {Observable} from 'rxjs';


@Injectable({
  providedIn: 'root',
})

export class SharedService{

    private acceptedBookings=[];

    public acceptedBookingsSubject= new BehaviorSubject<any[]>(['Hello World']);



    constructor(){ 
    }

addToAccepted(turno : Turno){

    this.acceptedBookings.push(turno);
    this.acceptedBookingsSubject.next(this.acceptedBookings);   


 }




}

И, наконец, 2-й компонент, который должен показать все принятые заказы. Я использовал как pipe (share ()), используя asyn c pipe, так и subscribe (), чтобы увидеть, сработал ли какой-либо, но оба просто показывают «Hello World», когда я вызываю console.log.

import { Component, OnInit} from '@angular/core';
import {SharedService} from '../../services/shared.service';
import {Observable} from 'rxjs';
import {Turno} from '../../models/turno';
import {share} from 'rxjs/operators';

@Component({
  selector: 'app-turnoaceptado',
  templateUrl: './turnoaceptado.component.html',
  styleUrls: ['./turnoaceptado.component.css'],
  providers:[SharedService]
})
export class TurnoaceptadoComponent implements OnInit {

        public acceptedBookings;
        public array:Observable<any[]>;
        public test;

          ngOnInit(): void {

            this.array = this._sharedService.acceptedBookingsSubject.asObservable();

            this.array.subscribe(response=>this.acceptedBookings=response);

            this.test=this.array.pipe(share());

            console.log(this.test);
            console.log(this.acceptedBookings);
  }

  constructor(private _sharedService: SharedService) { }

}

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Прежде всего, поскольку вы предоставляете сервис в root (provideIn: 'root'), вам необходимо удалить его из массива providers из ваших компонентов и любого другого модуля, если он там предусмотрен.

При передаче данных между компонентами с использованием субъектов вы должны иметь в виду, что вы отправляете эти данные из компонента в качестве полезной нагрузки с помощью метода next субъекта, но для «чтения» данных вы должны создайте новую наблюдаемую с субъектом в качестве источника (asObservable() метод), как вы делаете во втором компоненте.

В вашем сервисе:

@Injectable({
  providedIn: 'root',
})
export class SharedService{
    private acceptedBookingsSubject= new BehaviorSubject<any[]>(['Hello World']);
    public bookingListener$ = this.acceptedBookingsSubject.asObservable();

    constructor(){ }

    addToAccepted(turno : Turno){
    this.acceptedBookingsSubject.next(turno);   
  }
}

В вашем первом компоненте:

 acceptBooking(booking) {
   this._sharedService.addToAccepted(booking);  

   // you should move this in the OnInit life cycle hook but you need to remove the take operator or to increase the value
   this._sharedService.bookingListener$
    .pipe(take(1))
    .subscribe(console.log);
}

Во втором компоненте:

public acceptedBookings$: Observable<any[]>;

  ngOnInit(): void {
    this.acceptedBookings$ = this._sharedService.bookingListener$;

    this.acceptedBookings$.subscribe(console.log);
  }

Я создал этот стек Блиц , чтобы дать вам пример. Я надеюсь, что это поможет вам.

Совет: используйте канал async для отображения ваших данных и используйте оператор tap для побочных эффектов вместо ручной подписки в компоненте.

0 голосов
/ 23 апреля 2020

Код в вашем TurnosComponent и SharedService выглядит правильно.

Но в вашем TurnoaceptadoComponent ваши 'console.logs' находятся вне потока RX JS. Вы должны console.log внутри вашей подписки, например:

this.array.subscribe(response=> console.log(response));

Тогда вы сможете увидеть все значения, поступающие через поток.

...