Til*_*dam 5 rxjs angular2-changedetection angular angular-signals angular16
我正在尝试在 Angular 应用程序中切换到信号,目前在寻找良好实践方面遇到问题,并且我也经历了(至少对我来说)意外的行为。
这是我的代码片段,由一个 userService 和两个组件组成
export class UserService {
private user$: Observable<User>;
private refreshUser$ = new BehaviorSubject<void>(undefined);
constructor(private readonly http: HttpClient) {}
getUser(): Observable<User> {
if (!this.user$) {
this.user$ = this.refreshUser$.pipe(
switchMap(() => this.http.get<User>('...')),
shareReplay(1)
);
}
return this.user$;
}
reloadUser(): void {
this.refreshUser$.next();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有组件 A 为用户订阅:
export class aComponent {
currentUser: User;
constructor(private readonly userService: UserService) {
this.userService.getUser().subscribe((user) => {
this.currentUser = user;
});
}
}
Run Code Online (Sandbox Code Playgroud)
我有组件 aChild,它是组件 A 的子组件,也订阅用户并且还可以操作用户。它能够更改/删除用户的地址。在使用信号之前,我会立即更新组件的 currentUser 对象的地址,以便用户可以立即看到结果,并且我会从服务调用“reloadUser()”,以便全局用户是最新的,并且“A Component " 具有正确的值(这可能不是最好的解决方案,因为它会导致另一个 http 请求,但这不是这里的主题)。
export class aChildComponent {
currentUser: User;
constructor(private readonly userService: UserService) {
this.userService.getUser().subscribe((user) => {
this.currentUser = user;
});
}
changeAddress(newAddress: any) {
this.userService.updateAddress(newAddress).subscribe((updatedAddress) => {
this.currentUser.address = updatedAddress;
this.userService.reloadUser();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我使用发现的信号实现 aChild 组件后,我不必再调用“reloadUser()”,并且组件 A 的“currentUser”对象的值已经具有更新的地址。
export class aChildComponent {
currentUser: WritableSignal<User | undefined> = signal(undefined);
constructor(private readonly userService: UserService) {
this.userService.getUser().subscribe((user) => {
this.currentUser.set(user);
});
}
changeAddress(newAddress: any) {
this.userService.updateAddress(newAddress).subscribe((updatedAddress) => {
this.currentUser.mutate((user) => (user.address = updatedAddress));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道这是否是预期的行为,而是一种反模式,或者是否完全出乎意料,或者这种行为是否完全正常。但是我不完全理解为什么会发生这种情况以及它是如何工作的,因为在“A Component”中,在子组件中的信号发生变化后, getUser() 上的订阅不会被触发。每个引用的值都会发生变化。我还担心在这种情况下,当不再有 zone.js 并且应用程序仅与 Signals 配合使用时,更改检测将如何工作。由于在“A 组件”中, currentUser 不是信号,但它的地址无论如何都会发生变化(通过一些魔法),如何在我的 html 代码中检测到这种变化?
我实际上犯了一个错误和误解。信号并不是导致这种行为的原因,实际上与没有信号时的情况相同。
当订阅者更改重播主题的值时,似乎主题上的值也发生了更改,但没有发出。
我想如果我不想要这种行为我应该克隆该对象。
归档时间: |
|
查看次数: |
1163 次 |
最近记录: |