【问题标题】:How to trigger a filter of a BehaviorSubject stream when fromEvent("scroll') stream publishes?fromEvent("scroll') 流发布时如何触发 BehaviorSubject 流的过滤器?
【发布时间】:2016-09-07 07:47:42
【问题描述】:

前言: 我有一些不正确的程序代码,希望它能传达意图。我感觉像flatMapswitchMap这样的运营商会解决这个问题;然而,我仍然没有在 RXJS 中做出精神上的飞跃,以真正理解,如何或何时使用这些运算符。所以请多多包涵。

说明: 我有 2 个流:

  • var scrolling = Observable.fromEvent(target, 'scroll'); 正确捕获滚动事件。

  • var sampleFiltered = this.sampleElementsActiveCollection 表示当前满足规则/要求的偏移流:offset < 10 && offset > 0。例如元素距离窗口顶部 10 像素以内。

问题: 发生滚动事件时,如何在var sampleFiltered = this.sampleElementOffsetData 上触发过滤器? (这目前没有触发。)此外,我将如何清理嵌套订阅,因为它们目前只是为了传达意图而根本不工作。

import { Directive, HostListener } from '@angular/core';
import { ScrollerElementsStoreModel } from './scroller-elements-store.model';
import 'rxjs/add/operator/filter';
import {Observable} from "rxjs";
import {BehaviorSubject} from 'rxjs/Rx';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/filter';

@Directive({
  selector: '[mh-scroll]'
})
export class MhScroll {
  lastKnownScrollPosition: number;
  ticking: boolean;
  sampleElementOffsetData: BehaviorSubject<number[]>;

  constructor(private scrollElementsStore: ScrollerElementsStoreModel) {
    this.lastKnownScrollPosition = 0;
    this.ticking = false;
    this.sampleElementOffsetData = new BehaviorSubject([100,350]);
  }


    isElementCloseToTop(target) {

      var scrolling = Observable.fromEvent(target, 'scroll'); //this works


      var scrollingSub = scrolling.subscribe(
          (x) => { // this works.

            // this section below is completely wrong; 
            // however, hopefully shows intent, that when 
            // scrolling.subscribe triggers I want to run this filter.
            var sampleFiltered = this.sampleElementOffsetData.filter((x) => {
              var offset = x + this.lastKnownScrollPosition;

              // return when element offset is within 10px.
              return offset < 10 && offset > 0 
            },this);


            var sub =  sampleFiltered.subscribe(
              (y) => {
               // Update DOM.
              }
            )
          },
          (err) => {
            console.log('Error: %s', err);
          },
          () => {
            console.log('Completed');
          });

      this.ticking = false;
    }


    @HostListener('window:scroll', ['$event.target'])
    triggeredScroll(target) {
      this.lastKnownScrollPosition = window.scrollY;

      if (!this.ticking) {
        window.requestAnimationFrame(this.isElementCloseToTop.bind(this, target));
      }

      this.ticking = true;
    }
}

【问题讨论】:

  • sampleElementOffsetData 从哪里获取数据?谁喂它?
  • 这将是一堆指令,它们将进行自己的数学运算并传递有效负载,从而设置 sampleElementsOffsetData。我只是默认设置它不会使代码过于复杂
  • 您似乎有一些类型问题,行为主题在订阅时会发出一个元素[100, 350],但您的订阅处理程序会执行x + this.lastKnown...,其中x[100, 350]...
  • 简而言之,究竟什么是行不通的? // Update DOM. 代码块不会被执行吗?
  • 很抱歉,它今晚就退出了,但是。我在使用 mergeMap() 运算符而不是嵌套时得到了关闭。问题出在您指出的类型上。如果您想发布答案,我会 +1 最佳答案。

标签: javascript angular rxjs observable dom-events


【解决方案1】:

我的代码有 2 个问题: 1) BehaviorSubject Observable 中存在类型错误。过滤器只会遍历 Observables 而不是 Observables 值。

2) 我可以使用运算符 .mergeMap 来清理它 TL;DR: Map values from source to inner observable, merge output

var scrolling = Observable.fromEvent(target, 'scroll')
          .mergeMap(event => this.scrollElementsStore.elementUpdated.filter((event) => {
            var offset = event + this.lastKnownScrollPosition;
            console.log(event);
            return offset < 10 && offset > 0;
          }
        )).subscribe((x)=>{
          console.log(x, 'asdfasdf');
        })

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    相关资源
    最近更新 更多