通过 Angular 信号使用和更新对象

问题描述 投票:0回答:1

我一直在经常使用信号,但遇到了一个无法找到合理答案的用例。

许多在线示例和指南都展示了如何创建具有单个值的信号并通过 .set() 或 .update() 更新它。例如:

public value = signal<int>(0); value.set(1); 

这对于简单的输入来说非常有意义,但是当我们想要将信号与具有多个值的对象一起使用时会发生什么?或者我们想要多个输入?例如,如果我有一个 User 对象

export interface User { firstName: string, lastName: string }

该对象位于信号内部,

public currentUser = signal<User>({firstName: 'Doug', lastName: 'The Cat'});

我想要一个表单供用户更新他们的姓名,我如何更新各个值而不完全覆盖现有的用户对象?

我尝试创建信号输出的浅表副本,然后附加表单,然后调用信号上的 set 来更新属性,但这感觉不太好,因为我只是覆盖了那里的内容。

我还考虑过将每个值、firstName、lastName 转换为它们自己的信号,但是当值添加到诸如 streetAddress、poBox 等对象时,这会变得失控且不灵活。

angular signals
1个回答
0
投票

使用 update 方法来修补信号的值将是你最好的选择。在您的用例中,它的工作原理如下:

this.currentUser.update(x => ({ ...x, firstName: 'Danny' }));

使用扩展运算符创建新对象并仅设置修补的属性是一种常见做法,并且比直接更新属性有很多好处。信号特有的一个好处是,将信号用作“计算”信号的一部分时不会导致任何问题。如果您要直接更新属性,则计算出的信号将不会更新,因为对象引用从未更改。 如果您愿意,您还可以开发自己的可写信号版本,该信号专门用于对象并具有自己的

patch

方法。这将具有可在模板中使用的好处。 export type PatchableSignal<T extends {}> = Signal<T> & WritableSignal<T> & { /** Updates properties on an object */ patch(value: Partial<T>): void; }; export function patchableSignal<T extends {}>(initialValue: T, options?: CreateSignalOptions<T>): PatchableSignal<T> { const internal = signal<T>(initialValue) as SignalGetter<T> & WritableSignal<T>; const node = internal[SIGNAL]; return Object.assign(internal, { patch: (value: Partial<T>) => signalUpdateFn(node, (x) => ({ ...x, ...value })), }); }

<button (click)="currentUser.patch({ firstName: 'New Name' })">Click Me</button>
© www.soinside.com 2019 - 2024. All rights reserved.