【问题标题】:Angular 4 - ngFor for streamAngular 4 - 用于流的 ngFor
【发布时间】:2019-10-10 06:40:51
【问题描述】:

这是我的例子:

my-list.component.ts:

export class MyList implements OnInit {
  values: Observable<number>;
  ngOnInit(){
   this.values= Observable
    .from([1, 2, 3, 4, 5])
    .map(function (value) { return Observable.of(value).delay(2000); })
    .concatAll();
//    this.values.subscribe(x => console.log(x)); this is OK
  }
}

my-list.component.html:

<div *ngFor="let v of values|async">
  {{v}}
</div>

但我收到错误:

找不到“数字”类型的不同支持对象“1”。 NgFor 只支持绑定到 Arrays 等 Iterables。

我认为我可以使用“流”创建 ngFor。这是怎么做的?当然,我可以这样想:

.subscribe(x => this.data.push(x))
*ngFor="let v of values"

我不明白如何使用异步管道。谢谢

【问题讨论】:

  • console.log(values) 并显示输出
  • @bluray,当您创建 variable=Observable(...) 时,您将“变量”等同于 observable 而不是结果。您需要将 this.value=x 写入订阅函数
  • *ngFor 这里收到一个数字 - 1 - 作为参数。自然,它是不可迭代的。你的用例是什么?你想达到什么目标?
  • 我想在收到值时显示它们。首先会显示1,两秒后1,2 两秒后1,2,3...
  • 我以为是在做异步管道

标签: angular


【解决方案1】:

Angular 8 答案 - 应该转换为 Angular 4

Stackblitz

import { Component } from '@angular/core';
import { Observable, of, from, interval} from 'rxjs'
import { map, delay, tap, scan, skip, takeWhile } from 'rxjs/operators'

@Component({
  selector: 'my-app',
  template: `
    <div *ngFor="let v of values$|async">
      {{v}}
    </div>
  `

})
export class AppComponent  {
  values$: Observable<number[]>;
  ngOnInit(){

    // streams
    const counter$ = interval(1000)

    this.values$ = counter$.pipe(
      skip(1),
      scan((acc, cur) => {
        return [ ...acc, cur]
      }, []),
      takeWhile(arr => arr.length < 20) // <--- some end condition
    )
  }
}

异步管道没有什么特别之处,它接受一个 Observable 并在模板中为您订阅并在组件销毁时为您取消订阅。遵守在可观察流变量末尾使用 $ 的约定。

以下

<div *ngFor="let v of values$ | async">
  {{v}}
</div>

等价于

<div *ngFor="let v of values">
  {{v}}
</div>

您在 ts 文件中的哪个位置执行此操作

values$.subscribe(values => this.values = values)

【讨论】:

    【解决方案2】:

    concatAll 不会将结果连接到数组。而是让您的可观察数据(延迟数字)一个接一个地完成。我认为你想要实现的是

      this.values= Observable
        .from([1, 2, 3, 4, 5])
        .map(function (value) { return Observable.of(value).delay(2000); })
        .concatAll()
    //    .subscribe(x => console.log(x)); here this would emit 1 then 2 then 3 ...
        .scan((array, nextValue) => array.concat(nextValue), [])
    //    .subscribe(x => console.log(x)); here this would emit [1] then [1,2] then [1,2,3]... 
    

    有了这个scan,每次有新事件出现时,您都会得到聚合数组

    【讨论】:

      【解决方案3】:

      你可以使用 .scan() 操作符

      this.values= Observable
          .from([1, 2, 3, 4, 5])
          .map(function (value) { return Observable.of(value).delay(2000); })
          .concatAll().
          .scan((acc, value) => [...acc, value], []);
      

      它的行为很像数组上的 .reduce。 (rx .reduce() 操作符也会做同样的事情,但只有在 observable 完成时才会发出)

      【讨论】:

        猜你喜欢
        • 2018-06-13
        • 2018-02-13
        • 1970-01-01
        • 2017-10-07
        • 2017-11-13
        • 2018-04-06
        • 2018-01-01
        • 1970-01-01
        • 2018-03-25
        相关资源
        最近更新 更多