Angular 9: Observable Getter, возвращающий объект вместо Boolean из BehaviorSubject - PullRequest
0 голосов
/ 04 августа 2020

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

У меня есть BehaviorSubject, который отслеживает состояние как логическое значение. У меня также есть метод получения publi c, который является Observable, который возвращает BehaviorSubject. Я делаю это для того, чтобы не только подписаться на изменения в значении BehaviorSubject, но и получить текущее значение, если оно не изменилось. Хотя я могу получить правильное значение от подписки, я получаю объект, возвращаемый просто при вызове метода получения. Я хочу, чтобы он возвращал последнее значение.

Я пробовал использовать .getValue (), который, похоже, не работает, и я пробовал .value, который, похоже, работает, но выдает ошибку в IDE.

Я создал очень базовый c пример того, что я пытаюсь выполнить sh, и я поместил комментарии в файл my.service.ts, чтобы показать, что я м собираюсь. Пожалуйста, порекомендуйте. Спасибо!

РЕДАКТИРОВАТЬ: Я использовал то, что было в стеке блиц по умолчанию, и назначил геттер переменной name, чтобы увидеть это. Моя цель - получить значение, чтобы я мог что-то делать в зависимости от того, истинно это значение или нет. Я уверен, что мне не хватает чего-то очень простого.

EDIT: добавление кода в вопрос по запросу

EDIT: я также добавил .subscribe, чтобы показать это, хотя я понимаю, как Наблюдаемые работают, я также хочу проверить значение ВНЕШНЕГО изменения значения, используя тот же геттер, если это возможно.

MyService

import { Observable, BehaviorSubject } from "rxjs";

export class MyService {

  constructor() {}

  private _isBoolean = new BehaviorSubject<boolean>(false);

  public get isBoolean(): Observable<boolean> {
    //return this._isBoolean.value; // Returns boolean, but throws error "Type 'boolean' is not assignable to type 'Observable<boolean>'."
    return this._isBoolean; // Returns object, but I want the value
  }

}

AppComponent

import { Component } from '@angular/core';
import { MyService } from './my.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name;

  constructor(private _myservice: MyService) {
    this._myservice.isBoolean.subscribe(val => {
      console.log("value from subscribe: " + val)
    })

    this.name = this._myservice.isBoolean;
    if (this._myservice.isBoolean) {
      console.log("true!");
    } else if (!this._myservice.isBoolean) {
      console.log("false!");
    }
  }
}

https://stackblitz.com/edit/angular-hhdgrc

Ответы [ 4 ]

3 голосов
/ 04 августа 2020

Вы неправильно используете Observables. Добавьте, пожалуйста, вызов subscribe к observable:

this._myservice.isBoolean.subscribe((val) => {
    this.name = val;
    console.log("value: " + val);
});

Вы можете просто добавить код в обратном вызове subscribe, чтобы использовать изменяющееся значение:

Отредактировано app.component.ts

import { Component } from '@angular/core';
import { MyService } from './my.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name;

  constructor(private _myservice: MyService) {
    this._myservice.isBoolean.subscribe(val => {
      console.log("value from subscribe: " + val);


      this.name = val ;
      if (val) {
        console.log("true!");
      } else if (!val) {
        console.log("false!");
      }
    })

  }
}
1 голос
/ 04 августа 2020

Правильный способ использовать Boolean BehaviorSubject : -

определить следующим образом: -

_isBoolean: BehaviorSubject<boolean> = new BehaviorSubject(false);

обновить следующим образом: -

this._isBoolean.next(true); //  for true
this._isBoolean.next(false); // for false

чтение значения в каком-либо другом компоненте: -

this._isBoolean.subscribe(value => {
console.log(value);
    });

немедленное чтение текущего значения только один раз: -

this._isBoolean.asObservable().pipe(take(1)).subscribe(value => {
    console.log(value);
  });
0 голосов
/ 04 августа 2020

Спасибо Рахмату Али за то, что он привел меня к нужному мне ответу. Я даю здесь ответ, чтобы упростить поиск, предоставить более простой пример решения и лучшее объяснение.

Я хотел иметь функцию получения, которая позволила бы мне подписаться на изменения в значение BehaviorSubject, а также иметь возможность получать текущее значение без подписки в зависимости от текущей потребности.

Причина, по которой он не работает, заключается в том, что в следующем примере я заставил геттер возвращать наблюдаемый тип а не тип BehaviorSubject. Итак, я получал «правдивый» результат в консоли, потому что я проверял его наличие, а не логическое значение. Как только это изменилось, я смог получить доступ к логическому значению BehaviorSubject с помощью свойства .value.

Вот упрощенный пример решения (ПРИМЕЧАНИЕ: геттер не нужен, потому что, как только геттер вернул BehaviorSubject, Я мог бы изменить его значение с помощью .next без создания сеттера):

import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  private _isBooleanSubejct = new BehaviorSubject<boolean>(false);

  public get isBoolean(): BehaviorSubject<boolean> {
    return this._isBooleanSubejct;
  }

  constructor() {
    console.log(this.isBoolean.value);
    this.isBoolean.subscribe(val => {
      console.log(val); // false until the timer completed
      console.log(this.isBoolean.value); // false until the timer completed
    });

    setTimeout(() => {
      this.isBoolean.next(true);
    }, 5000);
  }
}
0 голосов
/ 04 августа 2020

Проблема заключается в html части приложения: служба возвращает наблюдаемый объект, на который шаблон должен подписаться. Для этого вам необходимо добавить конвейер asyn c в переменную шаблона

Добавить конвейер asyn c в компонент приложения. html переменную. Это поможет

<hello name="{{ name|async }}"></hello>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...