简体   繁体   English

当fromEvent(“ scroll')流发布时,如何触发BehaviorSubject流的过滤器?

[英]How to trigger a filter of a BehaviorSubject stream when fromEvent("scroll') stream publishes?

Preface: I have some incorrect procedural code with hopes, that it communicates intent. 前言:我有一些错误的程序代码,希望它能传达意图。 I have a feeling that an operator like flatMap or switchMap will solve this problem; 我感觉像flatMapswitchMap这样的运算符可以解决此问题; however, I still haven't made the mental leap in RXJS to really understand, how or when to use these operators. 但是,我仍然没有真正理解,如何或何时使用这些运算符的RXJS方面的精神飞跃。 So please bear with me. 所以,请忍受我。

Description: I have 2 streams: 说明:我有2个流:

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

  • var sampleFiltered = this.sampleElementsActiveCollection which is suppose to represent a stream of offsets that currently satisfy the rules/requirements: offset < 10 && offset > 0 . var sampleFiltered = this.sampleElementsActiveCollection ,它表示当前满足规则/要求的偏移量流: offset < 10 && offset > 0 eg Elements are within 10 pixels from the top of the window. 例如, 元素距离窗口顶部10像素以内。

Question: When a scroll event occurs, How do I trigger a filter on the var sampleFiltered = this.sampleElementOffsetData ? 问题:发生滚动事件时,如何在var sampleFiltered = this.sampleElementOffsetData上触发过滤器? (this is currently not triggering. ) Moreover, How would I clean up nested subscribes as they are currently just to communicate intent and not working at all. (目前还没有触发。)此外,我如何清理嵌套订阅,因为它们目前只是为了传达意图而根本无法工作。

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;
    }
}

There were 2 problems with my code: 1) there was a type error in the BehaviorSubject Observable.filter will only iterate over Observables NOT an Observables values. 我的代码有2个问题:1) BehaviorSubject Observable.filter中存在类型错误,它只会遍历Observables而不是Observables值。

2) I was able to clean this up using the operator .mergeMap TL;DR: Map values from source to inner observable, merge output 2)我能够使用运算符.mergeMap TL; DR清理此问题:将值从源映射到内部可观察的合并输出

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');
        })

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

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