Передача значения Observable переменной в базовом компоненте дочернему компоненту - Angular 5

Итак, у меня есть базовый компонент, и в нем у меня есть наблюдаемый внутри его конструктора, чтобы получить значение, как только оно будет получено внутри другого компонента, который будет проверять данные пользователя. Однако при попытке получить это значение в дочернем классе данные поступают как неопределенные. Ниже кода у меня проблемы:

Моя наблюдаемая:

@Injectable()
export class ObservableUsuario implements ObservableUtil {
    subject = new Subject<any>();
    setUsuario(variable: any) {
        this.subject.next({ text: variable });
    }

    clearUsuario() {
        this.subject.next();
    }

    getUsuario(): Observable<any> {
        return this.subject.asObservable();
    }

Здесь наблюдаемый установил:

 getValue = (refresh: boolean = true) => cacheable(
    () => this.http.get(`${environment.apiEndpoint}/api/Get/Value`, headers()).map(res => {
      this.observableUser.setUsuario(res.json());
      return res.json();
    }),
  );

Базовый компонент:

//more code
       perfilLotado: any;
        constructor(
            public observableUser: ObservableUsuario
        ) {
            this.observableUser.getUsuario().subscribe(
                perfil => this.perfilLotado = perfil.text.lotacaoDTO[0].perfilDTO[0].nome);
        }
//more code

Дочерний компонент:

   export class BaseListComponent extends BaseComponent {

        NgOnInit(){}

        validAction(situacao: number): any {
//Here appearer like undefined...
            console.log(this.perfilLotado);
            if (this.sistema.situacaoRestric[situacao] != undefined) {
                this.showMsg('warn', 'Mensagem de Alerta', this.sistema.situacaoRestric[situacao]);
                return false;
            } else if (this.sistema.situacaoRestric[situacao] == undefined && this.sistema.perfilRestrict[this.perfilLotado] != undefined) {
                this.showMsg('warn', 'Mensagem de Alerta', this.sistema.perfilRestrict[this.perfilLotado]);
                return false;
            } else if (this.sistema.situacaoRestric[situacao] == undefined && this.sistema.perfilRestrict[situacao] == undefined) {
                return true;
            }
        }

Другими словами, моя проблема заключается в загрузке значения, переданного моим наблюдаемым объектом, в класс дочернего компонента. ПРИМЕЧАНИЕ. Насколько я понимаю, это последний загружаемый компонент, как я могу заставить его загружаться раньше других компонентов экрана?


person Guilherme Caixeta    schedule 26.03.2018    source источник
comment
попробуйте переместить код, который подписывается на наблюдаемое, на ngOnInit   -  person Ricardo    schedule 26.03.2018
comment
Кто и когда вызывает getValue ()?   -  person Lynx 242    schedule 26.03.2018
comment
@ Рикардо, я пытаюсь, но не получается ...   -  person Guilherme Caixeta    schedule 26.03.2018
comment
@DiabolicWords внутри конструктора базового компонента при его загрузке.   -  person Guilherme Caixeta    schedule 26.03.2018
comment
вы можете включить содержимое шаблона вашего родительского компонента? Я хотел бы посмотреть, как вы передаете переменную ребенку   -  person Ricardo    schedule 26.03.2018
comment
И когда вы вызываете validAction () или лучше, кто вызывает этот метод?   -  person Lynx 242    schedule 26.03.2018
comment
@Ricardo Родительский компонент не имеет шаблона, он централизует общие системные функции. Я определяю значение переменной, которую буду использовать в дочернем компоненте родительского компонента.   -  person Guilherme Caixeta    schedule 26.03.2018
comment
@DiabolicWords. Внутри базового списка есть список, который определяет действие datadro, и в этом случае вызывается validAction ()   -  person Guilherme Caixeta    schedule 26.03.2018
comment
вы объявляете ObservableUsuario в модуле?   -  person Ricardo    schedule 26.03.2018
comment
@Ricardo, да декларирую в app.module   -  person Guilherme Caixeta    schedule 26.03.2018
comment
Я считаю, что вам следует переместить подписку на BaseListComponent в ngOnInit, я не думаю, что хороший шаблон имеет подписку на конструктор службы, но я не уверен, если вы можете, попробуйте передать метод подписки в компонент и оставьте сервис как можно более чистым   -  person Ricardo    schedule 26.03.2018
comment
@Ricardo Я добавил подписку в ngOnInit, но все еще продолжаю сталкиваться с той же проблемой. Содержимое внутри наблюдаемого всегда загружается последним, поэтому всякий раз, когда он обращается к нему в методе validAction (), он отображается как неопределенный, в случае, если он должен быть первым загружаемым элементом этого компонента ...   -  person Guilherme Caixeta    schedule 26.03.2018
comment
На мой взгляд, validAction следует читать из наблюдаемого perfilLotado, там вы должны подписаться и управлять своей логикой.   -  person Ricardo    schedule 26.03.2018
comment
@Ricardo Я только что проверил вашу идею, результат тот же. Не получилось как надо. Он выполняет функцию только тогда, когда он загружает экран, после этого он не получает к нему доступа больше функции, даже когда я пытаюсь вызвать его по событию.   -  person Guilherme Caixeta    schedule 26.03.2018
comment
Итак, читая здесь больше о наблюдаемых, я считаю, что ошибка могла быть в моей логике, поскольку к подписке можно получить доступ только в том случае, если происходит изменение значения данных, и я хочу получить доступ к этому значению после того, как это изменение уже произошло. Мне пришлось бы передать эти данные без ввода, потому что эти данные хранятся в другом компоненте и хранить их в кеше было бы нецелесообразно.   -  person Guilherme Caixeta    schedule 26.03.2018


Ответы (2)


Следуя вашему описанию, ваша проблема заключается в том, что вы подписываетесь на услугу и параллельно пытаетесь заполнить данные из конструктора. Вы бежите в каком-то состоянии гонки. Сам тестировал. Если вы подписались из своего конструктора, но вызывали метод setUsuario () службы из ngOnInit (), этого было бы достаточно, чтобы ваше значение присутствовало при вызове validAction ().

Эта сокращенная версия вашего кода работает, потому что подписка происходит в конструкторе, а «заполнение» позже - в ngOnInit ():

private perfilLotado: any;

constructor(private observableUsuario: ObservableUsuario) {
    this.observableUsuario.getUsuario().subscribe(
        perfil => {
            this.perfilLotado = perfil;
        });
}

ngOnInit(): void {
    this.observableUsuario.setUsuario('TEST');
}
person Lynx 242    schedule 26.03.2018

Да, это более или менее то же самое, однако, что данные были заполнены задолго до того, как эта часть кода была выполнена, поэтому я мог поймать ее только после того, как весь код был выполнен. Затем я смог решить с помощью BehaviorSubject, установив его вместе с другим Subject no service. Поскольку мне нужны два в разных точках, но из-за ошибки мне придется уйти, пока я не решу проблему.

Следуйте коду, который я использую в наблюдаемом:

@Injectable()
export class bObservableUsuario {

  private messageSource = new BehaviorSubject<any>("");
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(obj: any) {
    this.messageSource.next(obj)
  }

Услуга:

  GetData = (refresh: boolean = true) => cacheable(
    () => this.http.get(`${environment.apiEndpoint}/api/get/data`, headers()).map(res => {
//for now i need two observers here :(..
      this.observableUser.setUsuario(res.json());
//this bObservable solve my problems
      this.bObservable.changeMessage({obj: res.json()});
      return res.json();
    }),

Дочерний компонент:

@Component({ template: '' })
export class BaseListComponent extends BaseComponent {
    init() {
        this.bObservale.currentMessage.subscribe(d => this.perfilLotado = d.obj);

    }
///more code
person Guilherme Caixeta    schedule 26.03.2018