Angular5:对可观察量和订阅的澄清

时间:2018-03-31 02:42:43

标签: angular scroll observable subscription

我正在尝试动态加载数据,因为我向下滚动,以便它根本不必一次加载,而是在用户滚动时逐个加载。这张图片如下:

enter image description here

就目前而言,在正确保存数学信息的组件的初始化时,我使用订阅将屏幕上显示的定理数量绑定到我的服务所指示的数量。这样做是这样的:

bible.component.ts



import { Component, OnInit, AfterContentChecked } from '@angular/core';
import { BibleService } from './bible.service';
import {Theorem} from '../../model/theorem';
import {ElementRef, ViewChild} from '@angular/core';

@Component({
  selector: 'app-bible',
  templateUrl: './bible.component.html',
  styleUrls: ['./bible.component.scss']
})
export class BibleComponent implements OnInit {

  allTheorems: Theorem[];
  filtered: Theorem[];
  @ViewChild('theoremList') elementView: ElementRef;

  constructor(private service: BibleService) {}

  ngOnInit() {
    this.service.findAllTheorems()
      .subscribe(
        theorems => this.allTheorems = this.filtered = theorems
      );
  }

  search(search: string) {
    this.filtered = this.allTheorems.filter(theorem =>
      theorem.rule.includes(search) ||
       (theorem.name && theorem.name.toLowerCase().includes(search.toLowerCase())
    ));
  }
}




bible.service.ts



import {Observable} from 'rxjs/Observable';
import {Theorem} from '../../model/theorem';
import {AngularFireDatabase} from 'angularfire2/database';
import {Injectable, OnInit} from '@angular/core';
import {Subject} from 'rxjs/Subject';

@Injectable()
export class BibleService {

  pageSize = 10;
  private pageSizeSubscription;
  pageSizeChange: Subject<number> = new Subject<number>();

  constructor(private af: AngularFireDatabase) {}

  findAllTheorems(): Observable<Theorem[]> {

    return this.af.list('theorems', ref => {
      return ref.limitToFirst(this.pageSize).orderByKey();
    }).valueChanges().map(Theorem.fromJsonList);

    // return this.af.list('theorems').valueChanges().map(Theorem.fromJsonList);

  }

  updatePageSize(num) {
    this.pageSizeChange.next(num);
  }

}
&#13;
&#13;
&#13;

所以在我的init上的bible.component.ts中,我调用名为&#39; findAllTheorems&#39;的服务函数。并订阅返回的值,以便我的两个Theroem数组填充返回的值。 旁注是我对此订阅正在发生的事情的探索吗?这是否意味着如果由'findAllTheorems&#39;返回的值返回?更改然后我的数组将动态更新?

无论如何,我想要一些如何在我的服务中动态更改pageSize的值并更新页面,以便在用户向下滚动时显示更多定理?这是最好的方法吗? 总体当用户向下滚动时,将更多项目动态加载到列表中的最佳方法是什么?这样每次他们到达底部时,会有更多项目加载到底部?我还有一个观察者,只要命中div的底部就会记录到控制台,这意味着我可以调用一个函数来在命中时添加更多定理。

此外,findAllTheorems是一个可观察的意思究竟是什么意思?这基本上是说这个功能是开放的,可以订阅,以便其他功能或变量可以随时观察它的最新状态以保持最新状态?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

是的,您对订阅的解释是正确的,但您似乎并未将订阅存储在任何位置,这意味着您无法在销毁该组件后取消订阅。它会导致内存泄漏。

尝试这样的事情:

 private subscription: Subscription;

 ngOnInit() {
    this.subscription = this.service.findAllTheorems()
      .subscribe(
        theorems => this.allTheorems = this.filtered = theorems
      );
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

如果您不想强制处理订阅,请尝试使用异步管道。它将为您处理订阅。查看docs

对于无限滚动和动态加载内容,我会使用Intersection Observer。确保包含polyfill,因为目前全局浏览器支持率约为75%。

使用AngularFire的基本实现将是这样的:

  1. 创建InfiniteScroll指令,该指令在用户滚动到页面底部时发出。
  2. 每次InfiniteScroll指令发出时,使用AngularFire的dynamic querying运行新查询。