【发布时间】:2020-11-10 00:21:12
【问题描述】:
我有一个表格,里面有一个滑动切换开关,它根据我从 API 返回的数据加载为切换/未切换。这按预期工作。然后,用户可以切换此开关,这会导致将 POST 请求发送到 API。如果此 POST 失败,我想将切换开关重置到它最初加载的任何位置。我正在尝试通过在失败时再次发出原始 observable 来尝试此操作。我已通过浏览器中的控制台验证,这为切换提供了我期望的值,但是滑块没有相应移动。
在这一点上,我质疑我是否以正确的方式进行此操作,因为切换位置似乎不受该值更改时绑定的值的影响。我注意到垫子滑动开关有一个内置的toggle() 方法,我应该调用它吗?我想知道管理滑动切换位置的正确方法,因为我找不到任何文档。
组件.ts
ngOnInit() {
const lastItems$ = new ReplaySubject(1);
const getItemsAndCache = () => {
return this.myService
.getItems(this.accountId)
.pipe(
tap(itemsRes => lastItems$.next([...itemsRes])
)
)
};
geItemsAndCache().subscribe(items => lastItems$.next(items));
const updatedItems$ = this.itemChangeSubject.asObservable().pipe(
exhaustMap(itemChange =>
this.myService.changeItemToggle(
this.accountId,
itemChange.item.id
)
.pipe(
mergeMap(() => getItemsAndCache()),
catchError(() => lastItems$.pipe(first())
))
)
)
this.items$ = concat(lastItems$.pipe(first()), updatedItems$) as Observable<MyItem[]>;
}
onToggleChange(item: MyItem) {
this.itemChangeSubject.next({ item });
}
组件.html
<my--custom-table
[items]="items$ | async"
[displayedColumns]="displayedColumns"
[paginationOptions]="paginationOptions"
>
<ng-container matColumnDef="status">
<mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
<mat-cell *matCellDef="let item">
{{ item.status }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="toggled">
<mat-header-cell *matHeaderCellDef>Toggled?</mat-header-cell>
<mat-cell *matCellDef="let item">
<span>{{item.toggled}}</span>
<mat-slide-toggle
[(ngModel)]="item.toggled"
[disabled]="clicked"
(change)="onToggleChange(item); clicked = true"
></mat-slide-toggle>
</mat-cell>
</ng-container>
</my-custom-table>
【问题讨论】:
-
我没有看到问题,但我也看不到“onLockChange”的定义位置,问题可能存在,因为这可能是 POST 调用和潜在切换的原因
-
复制/粘贴时误漏了该行,已添加
-
不幸的是,这实际上只是将问题推回了一层,我不确定“itemChangeSubject”是做什么的,而且我看不到您在哪里设置 item.toggled,所以我可以不评论可能出现的问题。我建议您从一组非常基本的代码开始(就像我在答案中包含的那样),然后逐步构建其余的组件功能,以确保您不会弄乱切换
-
抱歉,它只是一个 ReplaySubject,其中包含单击切换的项目(只是表中的一行)。
private lockChangeSubject: ReplaySubject<{ item: MyItem; }> = new ReplaySubject();我认为我不需要显式设置 item.toggled,因为我正在设置this.items$。我最初的 GET API 调用 (getItemsAndCache()) 返回$items,然后将其传递给我的表进行迭代,每个项目上的一个道具是toggled。在我的 POST 失败时,我发现了错误和lastItems$.pipe(first()),它应该发出原始的 observable -
然后在这里执行此操作
this.items$ = concat(lastItems$.pipe(first()), updatedItems$) as Observable<MyItem[]>;应该会更改 $items,然后相应地更新表和切换,因为我使用的是异步管道。