javascript 使用 Observable 检测变量的变化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46132012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 06:29:14  来源:igfitidea点击:

Using an Observable to detect a change in a variable

javascriptrxjsobservable

提问by Jus10

I think I misunderstand how Observables are supposed to be used. I want to put a value in, and when the value changes it should emit the new value. I thought that was what they were for, but all the tutorials and docs don't seem to do this, but at the same time, I always see them being applied this way. For example, in angular when you subscribe to a "FirebaseListObservable", when the value in firebase changes it fires off a snapshot in the subscription. I want to make that for my own variable. Let's say I just have a string variable, and when it changes, it fires off any subscriptions.

我想我误解了 Observables 应该如何使用。我想放入一个值,当值改变时它应该发出新值。我认为这就是它们的用途,但所有教程和文档似乎都没有这样做,但与此同时,我总是看到它们以这种方式应用。例如,在 angular 中,当您订阅“FirebaseListObservable”时,当 firebase 中的值发生变化时,它会触发订阅中的快照。我想为我自己的变量做那个。假设我只有一个字符串变量,当它发生变化时,它会触发任何订阅。

回答by Jonathan002

Normally I would have my observables in services that get subscribed to in components, but I bundled them all in one class for the convenience of this answer. I've listed comments explaining each step. I hope this helps. : )

通常我会将我的 observables 放在组件中订阅的服务中,但为了这个答案的方便,我将它们全部捆绑在一个类中。我列出了解释每个步骤的注释。我希望这有帮助。:)

import { Subject } from 'rxjs/Subject';

export class ClassName {
    // ------ Creating the observable ----------
   // Create a subject - The thing that will be watched by the observable
   public stringVar = new Subject<string>();

   // Create an observable to watch the subject and send out a stream of updates (You will subscribe to this to get the update stream)
   public stringVar$ = this.stringVar.asObservable() //Has a $ 

   // ------ Getting Your updates ----------
   // Subscribe to the observable you created.. data will be updated each time there is a change to Subject
   public subscription = this.stringVar$.subscribe(data => {
         // do stuff with data
         // e.g. this.property = data
   });

  // ------ How to update the subject ---------
   // Create a method that allows you to update the subject being watched by observable
   public updateStringSubject(newStringVar: string) {
     this.stringVar.next(newStringVar);
   }
   // Update it by calling the method..
   // updateStringSubject('some new string value')

   // ------- Be responsible and unsubscribe before you destory your component to save memory ------
   ngOnDestroy() {
     this.subscription.unsubscribe()
   }
}

回答by bash

Try this using ReplySubject. I used typescript, angularfire to explain in the below code example

试试这个使用ReplySubject. 我在下面的代码示例中使用了 typescript、angularfire 来解释

export class MessageService {
  private filter$: ReplaySubject<any> = new ReplaySubject(1);

  getMessagesOfType():FirebaseListObservable<any>{
   return this.af.database.list(this.messagesPath, {
    query: {
      orderByChild: 'type',
      equalTo: this.filter$
    }
  });
  }
  getClosedMessage(): void {
    this.filter$.next('closed');
  }
  getOpenMessage(): void {
    this.filter$.next('open');
  }
}

// in some other class
// MessagesSubject is assigned to messageService 
this.messageService.getMessagesOfType().subscribe((listOfMessages)=>{
 // this list will be updated when the this.filter$ updated see below functions
 console.log(listOfMessages); 
});
// update this.filter$ like this to get 
this.messageService.getClosedMessage();
// to get open messges in 
this.messageService.getOpenMessage();