我想使用一个可观察的<字符串[]>在我的ANGLE应用程序的组件上逐渐显示内容.

  1. 在第TypeScript条中,我宣布:
export class ResultComponent implements OnInit{
 
 message: string = 'my message for user';
 spreadedMessage$: Observable<string> = from(this.message);
 progressiveMessage:string = "";

 ngOnInit() {
    let interval = 1
    this.obsMessage$
      .pipe(
        tap((letter) => {
           delay(35*interval),
           this.progressiveMessage += letter;
          interval++
        })
      )
      .subscribe();
    }
}
  1. progressiveMessage绑定到模板

<div> {{ progressiveMessage }} </div>

我的完整代码listing can be found here


我try 了第二种方法,效果很好,如下所示,但我想了解一下我使用Observable来取得进步有什么问题.

我的替代解决方案:

  1. spreadedMessage$: Observable<string> = from(this.message);更改为spreadedMessage: string[] = [...this.message];

  2. OnInit()方法上声明这一点:

for (let i: number = 0; i < this.spreadedMessage.length; i++) {
        setTimeout(() => (this.spaceMessager += this.spreadedMessage[i]), 35 * i);    
}

有什么主意吗?

推荐答案

在您的第一个示例代码中,delay()什么也不做!您已将其包含在tap运算符中,这是不正确的.它需要直接在.pipe()内.

然而,即使你把它放在正确的位置,我认为让它像你希望的那样工作是很棘手的,因为延迟持续时间不是针对每一次emits 进行判断的,它只使用初始值interval判断一次,

我认为这would个左右是可行的:

  ngOnInit() {
    this.spreadedMessage$.pipe(
      concatMap(letter => of(letter).pipe(delay(35))),
      tap(letter => this.progressiveMessage += letter),
    ).subscribe();
  }

在这里,我们 for each emits 返回一个新的concatMap以内的可观测值,这允许 for each emits 的字母计算延迟间隔.


但是,如果您只是简单地try 以恒定的间隔一次emits 一个角色,使用interval Creator函数可能会更容易,如下所示:

    interval(35).pipe(
      map(i => this.message[i]),
      take(this.message.length),
      tap(letter => this.progressiveMessage += letter),
    ).subscribe();

由于interval会发出从0开始的递增整数,因此我们可以将其用作要发出的字符的索引.

一旦emits 的数量达到消息的长度,我们就使用take操作符结束流.


为了进一步简化,我们可以减少外部变量progressiveMessage变量,只发出message字符串中我们感兴趣的部分.

  interval(35).pipe(
    map(i => this.message.slice(0, i+1)),
    take(this.message.length),
  ).subscribe();

而且,如果您想要进一步简化,可以将值定义为一个可观察的值,并利用模板中的async管道.这样就不需要订阅和使用ngOnInit:

  progressiveMessage$ = interval(35).pipe(
    map(i => this.message.slice(0, i+1)),
    take(this.message.length),
  );
<p>
  {{ progressiveMessage$ | async }}
</p>

这里有一个小的StackBlitz个例子.

Angular相关问答推荐

Angular ngModel双向数据绑定不适用于表单中的Select元素

如何在自定义验证器中获取所有表单控件(字段组动态创建)

角部炎问题

使用当前选定的选项创建IF语句

Toastr在独立组件上的Angular17实现

P-DropDown不会使用react 式表单手动设置Value

如何将参数传递给Angular 服务

Angular 懒惰地加载一个服务

完成行为主体

以 Angular 形式添加动态控件失败

模块内的命名路由出口 - 路径匹配但内容未加载

Angular:组件的内容投影访问数据

多个 Mat Paginator 在 Angular 组件中不起作用

无法卸载 angular-cli

如何在 Angular4 中访问组件的 nativeElement?

如何在 Angular 2 中正确设置 Http 请求标头

Angular 2中基于Condition条件的点击事件

AOT - Angular 6 - 指令 SomeComponent,预期 0 个参数,但go 有 1 个参数

如何在 angular2 中的 div 的 contenteditable 上使用 [(ngModel)]?

No provider for Router?