Angular 角度RxJs:从observable获取最后一个或默认值

Angular 角度RxJs:从observable获取最后一个或默认值,angular,typescript,rxjs,Angular,Typescript,Rxjs,我已经从“单击”按钮事件创建了一个可观察的: let editClick$ = Observable.fromEvent(this.editButton.nativeElement, 'click'); 因此,当单击“编辑”按钮时,表示用户正在编辑: this.editing$ = editClick$.pipe(map(() => true)); “编辑”按钮出现问题 未单击(默认值必须为false),或 订阅服务器应接收最后发出的值 有什么想法吗?我认为你的第二个要求是“当一个新订

我已经从
“单击”
按钮事件创建了一个
可观察的

let editClick$ = Observable.fromEvent(this.editButton.nativeElement, 'click');
因此,当单击“编辑”按钮时,表示用户正在编辑:

this.editing$ = editClick$.pipe(map(() => true));
“编辑”按钮出现问题

  • 未单击(默认值必须为
    false
    ),或
  • 订阅服务器应接收最后发出的值

  • 有什么想法吗?

    我认为你的第二个要求是“当一个新订户订阅时,他希望立即获得最新的价值”。这样就可以了:

    this.editing$ = editClick$.pipe(
      map(() => true),
      startWith(false), // <- this will be the starting value
      shareReplay(1) // <- the last emitted value will be saved and emitted immediately when a new subscriber subscribes
    );
    
    this.editing$=editClick$.pipe(
    映射(()=>true),
    
    startWith(false),//我很高兴您选择从
    fromEvent
    创建一个可观察的事件(请注意,您显示信号的语法和RxJS的旧(不推荐)版本,您运行的是什么版本?我将使用最新版本作为示例)

    我想对于第一个问题,您需要
    startWith()

    您将这样使用它:

    fromEvent(this.editButton.nativeElement, 'click').pipe(
        map(() => true),
        startWith(false)
    )
    
    第二个问题有点复杂,因为默认情况下,
    fromEvent()
    可观察的
    完成
    。这为您提供了两个选项,这在很大程度上取决于您的用例

    想到的运营商:
    take(x)
    其中x是要接受的值的数量。如果这是第一个值,
    first()
    也起作用

    debounceTime(ms)
    ,它缓冲所有输入并仅在经过去盎司毫秒后发射。您可以在这之后添加一个
    take(1)
    ,使其在之后完成


    也许,如果您可以扩展您的用例,我们可以帮助您确定哪些运算符或它们的组合会有所帮助。

    为了生成默认值,将返回:

    this.editing$.pipe(publishBehavior(), refCount());
    
    它类似于
    share()
    操作符,但是
    share()===多播(()=>newsubject())。refCount()


    我建议您看看这个。

    我想您不需要startWith(false),因为订阅者可能获得2次发射,而您只需要1次发射。 这个怎么样:

    this.editing$ = editClick$.pipe(
    mapTo(() => true),
    defaultIfEmpty(false),
    );
    

    也许你在寻找一个行为主体。大多数人不是在寻找一个主体。你有一个非常好的可观察对象。使用它的80个操作符中的一个来获得你想要的。shareReplay()是如何实现的这里的帮助?它没有完成。他想要接收最后发出的值。shareReplay完成了这一点。它…没有?它使可观察到的内容变热。
    editClick$
    是一个
    fromEvent
    流,默认情况下,它永远不会完成。
    shareReplay()
    只是把它作为一个
    ReplaySubject
    隐藏在引擎盖下。这将完成的唯一事情是在订阅时发出最后一个已知值。这是非常低效的。这不是非常低效,这正是他想要的:我将“订阅者应该接收最后发出的值”读为“保存最后一个值并为新订阅者发出它”。因此,缓存一个值并不是坏事,但在本用例中需要。请删除您的否决票。在我更改任何内容之前,我将让@Jordi说明您的假设是否正确。无正当理由使用
    主题的建议(他已经为他的可观察对象使用了一个非常好的创建操作符,这里不需要一个主题)对我来说似乎是一个糟糕的做法,而且做得太多了。为什么用
    publishBehavior()
    而不是
    publishLast()
    ?因为
    publishBehavior()
    也是
    多播()
    。顺便说一句,
    publishLast()
    也一样,但它似乎与您想要的内容有更多的联系;最后一个值。
    publishLast
    需要源代码完成。当我写下我想要接收最后发出的值时,我的意思是“最近发出的值”…好的。
    publishReplay(1)
    将实现完全相同的效果,并将其缓冲区限制为一个。我的主要问题是,您有一个功能良好的热可观察对象,因为您使用了一个
    创建操作符,而您使用的是另一个“内部”主题来实现这一点。老实说,我不知道哪位操作员会在不创建主题的情况下为您提供所需的
    replay
    行为。至少这不是作为安慰奖的手动操作。;-。尽管如此,我还是投了更高的票,尽管我不完全确定
    refCount()是否
    是必需的。任何
    publish()
    操作符都是
    multicast()