简体   繁体   English

如何从 Observable Angular 中获取初始值 8+

[英]How get initial value from an Observable Angular 8+

I have a page form with values already setted, previous and next button elements.我有一个页面表单,其中包含已设置的值、上一个和下一个按钮元素。

At ngOnInit, I'm getting a List with 3 items from an observable , as initial value - sometimes I get 4 items .在 ngOnInit,我从一个observable中得到一个包含 3 个项目的列表作为初始值——有时我得到 4 个项目

Before I go to the next page I have to click, necessarily , on a button that will call the function calculate() that will make a request and my observable List will have 4 items.在我 go 到下一页之前,我必须单击一个按钮,该按钮将调用 function calculate()将发出请求,我的可观察列表将有 4 个项目。

So, when I click on next button onNextButton() I would like to use the initial value to compare with the current, if they are the same, or check if this list had any changes (any incrementing).因此,当我单击下一个按钮onNextButton()时,我想使用初始值与当前值进行比较,如果它们相同,或者检查此列表是否有任何更改(任何递增)。

The way that I'm doing, I'm not manage to keep/store the first value.我这样做的方式,我无法保留/存储第一个值。 On next button click, i'm getting the updated value, instead the previous.单击下一个按钮时,我将获得更新的值,而不是之前的值。

My code:我的代码:

export class PageComponent implements OnInit {

   questions$: Observable<any[]>;
   hasChange: boolean;

   ngOnInit() {

     // GETTING INITIAL VALUE
     this.questions$.subscribe((quest: any[]) => {
        this.hasChange = quest.length > 3 ? true : false
     });
   }

   calculate() {
      // calling a request
      // at this point, my observable will update and will have 4 items.
   }

   onNextButton() {
      if (hasChange) {
         // submit()
      } else {
         // navigate()
      }
   }
}

So, in this scenario the initial value should be a list w/ 3 items, but i'm getting 4 and its breaking my logic...所以,在这种情况下,初始值应该是一个包含 3 个项目的列表,但我得到 4 个,这打破了我的逻辑......

How do I get the previous value of Observable and store it in a variable?如何获取 Observable 的先前值并将其存储在变量中? Or, how can I detect any changes?或者,我怎样才能检测到任何变化?

I tried behavioursubject and pairwise from RxJS, but I'm not sure how to apply it.我从behavioursubject尝试了 behavioursubject 和pairwise ,但我不确定如何应用它。

Thank you!!!谢谢!!!

As you stated, you must use ReplaySubject or BehaviourSubject, since Observable does not have that "memory" for retrieve last emitted value.如您所述,您必须使用 ReplaySubject 或 BehaviourSubject,因为 Observable 没有用于检索最后发出的值的“内存”。 ReplaySubject and BehaviourSubject are similar, both send last emitted value on subscription, but ReplaySubject only emits last emitted value on subscription and BehaviourSubject stores a list of last emitted values (configurable size). ReplaySubject 和 BehaviourSubject 相似,都在订阅时发送最后发射的值,但 ReplaySubject 仅在订阅时发射最后发射的值,而 BehaviourSubject 存储最后发射值的列表(可配置大小)。 I'll be using BehavoiurSubject since is a bit more complete.我将使用 BehavoiurSubject 因为它更完整一些。

Just replace the Observable you were using with the BehaviourSubject, and keep in mind that you must definde that memory size when you instance the class. For example, you could create a method that returns a BehaviourSubject with last boolean stored like this:只需将您使用的 Observable 替换为 BehaviourSubject,并记住在实例化 class 时必须定义 memory 大小。例如,您可以创建一个返回 BehaviourSubject 的方法,最后一个 boolean 存储如下:

private fooBehaviourSubject;

function ngOnInit: void{
    this.fooBehaviourSubject = new BehaviorSubject<boolean>(1); // 1 is the "stack" size
    this.fooBehaviourSubject.next(true); // <- First value emitted here
}

function getValue: BehaviourSubject<boolean> {
    return this.fooBehaviourSubject;
}

When you subscribe like this:当您这样订阅时:

getValue().subscribe(e => console.log(e))

the last stored value (true) automatically will be retrieved and shown in console, but ensure you at least have emitted one first, or you wont execute the subscription until one next method is called.最后存储的值 (true) 将自动检索并显示在控制台中,但请确保您至少首先发出一个值,否则在调用下一个方法之前您不会执行订阅。 After that, every update of the value will trigger that console.log with the updated value.之后,该值的每次更新都将使用更新后的值触发该 console.log。


Applied to your code, you could create the BehaviourSubject in the ngOnInit, subscribe to it also in the ngOnInit to define the callback event, and call the next method of the BehaviourSubject once the list must be updated.应用于您的代码,您可以在 ngOnInit 中创建 BehaviourSubject,也在 ngOnInit 中订阅它以定义回调事件,并在必须更新列表时调用 BehaviourSubject 的 next 方法。

export class PageComponent implements OnInit {

    questions$: Observable<any[]>
    hasChange: boolean

    ngOnInit() {

        // GETTING INITIAL VALUE
        let hasSome = false

        this.questions$
            .subscribe((quest: any[]) => {
               
               // ### This is works for me!
               hasSome = quest.some(item => item.id === 'whatever')
               
               // ### This is the way that I was trying to do. 
               // ### Is's not wrong but didn't work for me =( 
               // this.hasChange = quest.some(item => item.id === 'whatever')
        )
        this.hasChange = hasSome
    }

    calculate() {
        // calling a request
        // at this point, my observable will update and will have 4 items.
    }

    onNextButton() {
        // ### Now this.hasChange is assigned once and where I want, OnInit.
        if (this.hasChange) {
            // submit()
        } else {
            // navigate()
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM