我可以使用角度信号来存储地图吗?

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

我开始使用 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 等数据结构一起使用吗? 变更检测能正常工作吗?

提前致谢。

angular typescript dictionary signals
1个回答
0
投票

请注意这一点

基本类型 -> 数字、字符串、布尔值、未定义、空值和符号 当实际值改变时信号触发( 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));
    }
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.