【问题标题】:Using an Observable to detect a change in a variable使用 Observable 检测变量的变化
【发布时间】:2017-09-09 15:06:30
【问题描述】:

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

【问题讨论】:

  • 如果您想自己将新值放入流中,您需要一个Subject,而不仅仅是一个Observable。大多数 Observables 实际上是只读的。但这不一定检测变化,你必须自己管理它。
  • 是的,谢谢。研究 observables 的时间如此之多,甚至没有人提到过 Subject。这更有意义。谢谢你的澄清!
  • 如果有用的话,我在这里写了一些关于我们如何使用主题的文章:blog.jonrshar.pe/2017/Apr/09/async-angular-data.html
  • 哦,等等,rxjs 中的任何地方都没有内置的变量变化检测?我必须手动解决?我绝对认为这是一个内置功能lol

标签: javascript rxjs observable


【解决方案1】:

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

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()
   }
}

【讨论】:

  • 这很棒。 Subjects 不是已经是 Observable 了吗?订阅主题本身和订阅可观察版本的主题有区别吗?
  • 假设拍摄对象是某种动物,而可观察对象是记录拍摄对象的相机。如果对象睡着了,则 observable 将作为事件流睡着。您可以通过在电视上观看动物星球的纪录片来订阅此内容哈哈
  • 但从技术上讲,是的,该主题确实需要存在才能让 observable 观察它们并将更改发送到您活动的任何订阅
  • 很高兴能帮上忙 ^^
  • 这简直太完美了,想要一个这样的例子,简单干净
【解决方案2】:

使用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();

【讨论】:

  • 不是我想要的。在这种情况下,FirebaseListObservable 正在为我们进行更改检测,它基于数据库中的更改。我只是想在一个字符串变量上实现变化检测。
猜你喜欢
  • 2016-08-16
  • 2022-07-11
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多