gpt4 book ai didi

angular - 如何从封装在服务中的流中获取被检查的用户?

转载 作者:行者123 更新时间:2023-12-04 14:46:34 25 4
gpt4 key购买 nike

有服务UsersService包含用户逻辑:

interaface User {
id: number,
name: string,
checked?: boolean;
}

class UserService {
public users$ = new BehaviorSubject<User[]>([]);
public load() {
this.http.get('users').subscribe((users: Users[] => this.users$.next(users));
}

public get users() {
return this.users$.asObservable();
}
}
我从组件内部的服务获取数据:
public users$: Observable<User[]>;
constructor(private userService: UserService) {
this.users$ = this.userService.users;
}
模板是:
<div> *ngFor="let user of users$ | async">
<div>{{ user.name }}</div>
<div><mat-checkbox [(ngModel)]="user.checked"></mat-checkbox></div>
</div>
<div>Checked users: {{ checkedusers | json }}</div>
如何使用 rxjs 方法获取所有选中的用户 {{ checkedusers | json }}更新一个复选框或所有复选框后来自流和 封装它投入使用?

最佳答案

使用 scan 运算符将所有可以修改用户列表的源合并到一个流中。然后在组件中,不是直接修改用户对象,而是将更改发送到用于修改列表的主题之一:
服务

class UserService {
readonly loadUsersSubject = new Subject();
readonly userChangeSubject = new Subject<[userId: number, Partial<User>]>();

readonly users$ = combineLatest([
this.loadUsersSubject.pipe(
switchMap(() => this.http.get('users')),
map((users) => (s) => users))
),
this.userChangeSubject.pipe(map(([userId, partialUser]) => (s) => {
const index = s.findIndex(x => x.userId === userId);
return [...s.slice(0, index - 1), { ... s[index], partialUser }, ...s.slice(index + 1)]
})
]).pipe(
scan((s, reducer) => reducer(s), []),
shareReplay(1)
)
}

模板
<div> *ngFor="let user of users$ | async">
<div>{{ user.name }}</div>
<div><mat-checkbox [ngModel]="user.checked"
(ngModelChange)="userService.userChangeSubject.next([user.id, { checked: $event.checked }])"></mat-checkbox></div>
</div>
<div>Checked users: {{ checkedusers$ | async | json }}</div>
几点意见:
  • 您不必直接在服务上就该主题调用 next 电话。为了简洁起见,我在示例中这样做了。如果那是你的事,请随意将它们包装在方法中。
  • 元组的使用再次是为简洁起见而做出的另一个决定。
  • 服务中的每个主题都返回一个 reducer ,它本身将返回用户数组的新副本。这就是为什么当单个用户发生变化时,我会创建一个全新的用户。我本可以将值分配给现有数组的元素,但我已经养成了不改变任何变量的习惯。
  • 如果您需要查看已检查的用户,则从 users$ observable 映射一个过滤后的数组:users$.pipe(map(x => x.filter(y => y.checked))) .
  • 关于angular - 如何从封装在服务中的流中获取被检查的用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69905357/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com