我开始使用 Angular 新的 Signals API。但有人告诉我,在使用信号时我们需要将数据视为不可变的。
我不确定我是否可以使用 JS Maps 做这样的事情:
// code in my service.
// I'm using this Map to save the messages in a object and get the messages by queue name.
messages = signal(new Map<string, Object>());
queryForMessagesInQueue(queue) {
this.httpClient.get('...').subscribe((newMessagesArray) => {
const messages = this.messages().get(queue) || {};
// validate if newMessages already exists in the message object
let addedMessages = 0;
newMessagesArray.forEach((newMsg) => {
const messageExists = !!messages[newMsg.id]
if (messageExists == false) {
messages[newMsg.id] = newMsg;
addedMessages++;
}
});
if (addedMessages !== 0) {
this.messages.update((msgMap) => msgMap.set(queue, messages));
}
});
}
然后,在我的组件中我正在做这样的事情:
export class MyComponent {
private service = inject(MyService)
messages = service.messages; // this is the service signal.
}
我的使用方法正确吗?
信号可以与 JS Maps 等数据结构一起使用吗? 变更检测能正常工作吗?
提前致谢。
请注意这一点
基本类型 -> 数字、字符串、布尔值、未定义、空值和符号 当实际值改变时信号触发( 1 != 2 -> 改变触发)
非原始类型 -> 对象、数组等。 作为参考存储在内存中。
内存引用更改时会触发信号( memref != memref2 更改触发)
此外,当您更改非基本类型的嵌套属性时,引用不会更改!
不,使用地图作为信号不是一个好主意,原因是,您只能更新地图内部内容的引用,但如果不转换,您将无法更新地图的引用到一个物体。
更好的想法是将映射的内部值转换为信号,因为您将能够使用数组解构来更新内部数组信号的引用。
// code in my service.
// I'm using this Map to save the messages in a object and get the messages by queue name.
messages = new Map<string, Object>();
queryForMessagesInQueue(queue) {
this.httpClient.get('...').subscribe((newMessagesArray) => {
const messages = this.messages.get(queue) || {};
// validate if newMessages already exists in the message object
let addedMessages = 0;
newMessagesArray.forEach((newMsg) => {
const messageExists = !!messages[newMsg.id]
if (messageExists == false) {
messages[newMsg.id] = signal(newMsg); // <- changed here
addedMessages++;
}
});
if (addedMessages !== 0) {
// this.messages.update((msgMap) => msgMap.set(queue, messages));
}
});
}