标签: async-pipe

Angular:在异步调用和 AsyncPipe 后创建动态反应表单

我执行异步服务调用来获取元素列表。

 public elementList: Array<Element>;
   ... 
   this.service.getElementList().subscribe( list => {
       this.elementList = list;
       this.createFormGroup(list);
     }
   );
   ...
Run Code Online (Sandbox Code Playgroud)

当我收到元素列表(我订阅了服务调用)时,我根据元素列表构建表单组。在模板中,我有一个 *ngIf 仅当列表大于零时才绘制。

*ngIf="elementList?.length>0"
Run Code Online (Sandbox Code Playgroud)

由于elementList是异步获取的,所以这个ngIf不起作用。我读到可以将 ngIf 与 AsnycPipe 一起使用。所以在模板中我将有:

*ngIf="elementList$ && elementList$.length>0"
Run Code Online (Sandbox Code Playgroud)

其中 elementList$ 是从服务调用返回的 Observable。

   public elementList$: Observable<Array<Element>>;   

   elementList$ =this.service.getElementList()
Run Code Online (Sandbox Code Playgroud)

我想知道收到 elementList 后如何创建 FormGroup。首先,我需要创建 FormGroup,然后模板应该调用 *ngIf 来绘制元素。

angular angular-reactive-forms async-pipe

5
推荐指数
2
解决办法
4726
查看次数

如何将材质表与异步管道和更改检测一起使用?(无法正常工作)

我花了大约三天的时间试图解决这个问题。

预期行为:材质表始终使用后端的最新数据进行渲染。当从单独的组件将新项目添加到表中时,路由器重定向到页面会显示更新的数据。

实际行为:第一次导航到页面时,表格为空。表格已呈现,列标题已呈现,但未填充任何行。导航离开然后返回可以正确填充表格。当向表中添加新项目时,服务会将该项目发送到后端,然后调用所有项目。然后该服务会更新商店(另一项服务)。重定向到表格组件时,表格似乎快速闪烁旧数据,然后再次显示为空白。一旦我离开并返回,表格就会正确加载。

我正在将下面的异步管道与服务一起使用。这对我来说似乎不对......此外,ngOnChanges 没有记录任何内容。

应用商店.service.ts

private _pets: ReplaySubject<Pet[]> = new ReplaySubject(1);
public readonly pets: Observable<Pet[]> = this._pets.asObservable();
getPets(): Observable<Pet[]> {
    return this.pets;
}
Run Code Online (Sandbox Code Playgroud)

appDispatch.service.ts

public getPets(): Observable<Pet[]> {
    return this.appStore.getPets();
}

private setPets(pets: Pet[]) {
    this.appStore.setPets(pets);
}
Run Code Online (Sandbox Code Playgroud)

petTableComponent.component.ts

...
changeDetection: ChangeDetectionStrategy.OnPush

constructor(private appDispatch: AppDispatchService,
              private router: Router) {
}

ngOnChanges(changes: SimpleChanges): void {
    console.log(changes.value.currentValue);
}
Run Code Online (Sandbox Code Playgroud)

petTableComponent.component.html

<table
  mat-table
  [dataSource]="appDispatch.getPets() | async" multiTemplateDataRows
  class="mat-elevation-z8">

    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef scope="col" [attr.role]="null"> <h4>Name</h4></th>
      <td mat-cell *matCellDef="let element" scope="row" [attr.role]="null"> …
Run Code Online (Sandbox Code Playgroud)

angular-material angular mat-table async-pipe

5
推荐指数
1
解决办法
9531
查看次数

ngIf 异步管道作为仅进行空检查的值

我有一个可观察量,我想在 ngIf 中创建一个变量,并且仅在值为 null 时返回 false (可观察量返回一个数字)

我需要显式检查 null,因为我的 observable 可以返回 0 作为触发 else 块的值。

我尝试过以下方法

*ngIf="(observable$ | async) as obs; obs !== null; esle #elseTemplate"
Run Code Online (Sandbox Code Playgroud)
*ngIf="((observable$ | async) as obs) !== null; esle #elseTemplate"
Run Code Online (Sandbox Code Playgroud)
*ngIf="(observable$ | async) !== null; $implicit = obs; else #elseTemplate"
// this returns the boolean 
Run Code Online (Sandbox Code Playgroud)

我当前的解决方案看起来不太优雅是

*ngIf="(observable$ | async) !== null; esle #elseTemplate"
{{ observable$ | async }}
Run Code Online (Sandbox Code Playgroud)

我正在使用 Angular 10。

rxjs angular rxjs-observables async-pipe angular10

5
推荐指数
1
解决办法
4676
查看次数

异步管道向子组件发送“空”值

我想将一个值传递给子组件。这个值是一个 Observable,所以我使用异步管道。

<child [test]="test$ | async"></child>
Run Code Online (Sandbox Code Playgroud)

test$ 只是一个普通的可观察变量,它在一段时间(3000 毫秒)后发出值,模拟对服务器的 API 请求。

this.test$=timer(3000).pipe(
      mapTo("value")      
 )
Run Code Online (Sandbox Code Playgroud)

在子组件中,我只想检查test

@Input() test: any;

constructor(){
    console.log("child/test", this.test); //null
    setTimeout(()=>console.log("child/test (timeout)", this.test),4000) //value

   if(this.test){
     //maintain and check `this.test`
     //this code will not run, because at this point `this.test` is null.
     //we don't know the exact time that `this.test` will have a value
     //this causes that `this.test` is wrong

      this.checked=true 
     }
  }

Run Code Online (Sandbox Code Playgroud)
<div *ngIf="checked">{{test}}</div>
Run Code Online (Sandbox Code Playgroud)

我不想更改测试类型Observable并订阅它。我想直接接收最终值。我根本不想修改编辑组件。

使用ChangeDetectorRef手动触发变化检测器是不

@Input() test$:Observable

constructor(){
  this.test$.subscribe(v=>this.test=v)
}
Run Code Online (Sandbox Code Playgroud)

我还做了这个 …

observable rxjs angular-pipe angular async-pipe

4
推荐指数
4
解决办法
5460
查看次数

asynsPipe 生成 null 作为第一个值

当在 Angular 中使用异步管道时,不会立即触发事件(http 请求或任何有延迟的可观察值),第一个值null 是为什么会发生?如何避免这种情况?

<hello [data]="delayedData$|async"> </hello>
Run Code Online (Sandbox Code Playgroud)

第一个改变:

SimpleChange {
   currentValue: null
   firstChange: true
   previousValue: undefined
}
Run Code Online (Sandbox Code Playgroud)

第二个变化:

SimpleChange {
   currentValue: 'some real data'
   firstChange: false
   previousValue: null
}
Run Code Online (Sandbox Code Playgroud)

stackblitz 上的示例: https://stackblitz.com/edit/http-async-pipe-crxm32

rxjs angular async-pipe

2
推荐指数
1
解决办法
4080
查看次数

Angular 异步管道重新订阅

我对 Angular 异步管道的理解是,它在 HTML 模板中为您订阅公开的 Observable。例如

成分

export class TestComponent {
    let todos$: Observable<Array<Todo>>;

    constructor(private http: HttpClient) {}

    ngOnInit() {
        this.todos$ = this.http.get<Array<Todos>>(...)
    }
}
Run Code Online (Sandbox Code Playgroud)

模板

<div *ngFor="let todo of todos$ | async">
    {{ todo }}
</div>
Run Code Online (Sandbox Code Playgroud)

我的理解是 HttpClient Observable 将发出以下成功事件:

next(value)
completed
Run Code Online (Sandbox Code Playgroud)

和错误时

error(error)
completed
Run Code Online (Sandbox Code Playgroud)

当可观察对象发出已完成事件时,订阅将关闭。

因此,如果您订阅了像 Angulars HttpClient Observable 这样的冷 observable,您如何重试该 HttpClient 请求?

异步操作符执行初始订阅,但一旦冷可观察完成就会关闭,如果你想再次执行它,如何让异步操作符重新订阅?例如,如果您想刷新数据。

observable rxjs angular async-pipe

1
推荐指数
1
解决办法
2894
查看次数

模板中同一个可观察对象上的多个异步管道是否会导致更多更改检测?

我正在研究遗留的角度代码,原来的开发人员已经走了。我在模板中看到了很多异步管道。它会导致更多的变化检测吗?

模板:

      <div>{{(cart$ | async)?.name}}</div>
      <div>{{(cart$ | async)?.price}}</div>
      <div>{{(cart$ | async)?.count}}</div>
Run Code Online (Sandbox Code Playgroud)

我应该重构代码,让父组件模板异步管道cart$并将其传递给子组件吗?我知道这样代码更干净,除此之外,还有其他优点吗?谢谢!

<child [cart]="cart$ | async"></child>
Run Code Online (Sandbox Code Playgroud)

angular async-pipe

1
推荐指数
1
解决办法
923
查看次数