请教下 angular computed 相关的问题

320 天前
Mirachael  Mirachael

使用 computed 获取数组长度,但是视图不会更新

  addrLength = computed(() => {
    const user = this.dataService.user();

    return user.addresses.length;
  });

使用 computed 重新构建新的数组,视图也不会更新

  addresses = computed(() => {
    const user = this.dataService.user();
    // transform data 后页面不会更新
    // return user.addresses.map(addr => ({ address: addr, title: `Address-${addr.title}` }));

    // 直接返回 user.addresses ,页面会更新
    return user.addresses;
  });

这里是在线 demo

2617 次点击
所在节点   Angular  Angular
27 条回复
chnwillliu
chnwillliu
319 天前
@Mirachael 一个 signal 只有脏了才会 push dirty 的 notification 给下游的 computed ,effect 或者 view ,signal update 后脏不脏由 signal equality function 决定,默认用的 Object.is 检测前后两个值。所以并不需要 deep clone ,shallow clone 一样可以。

直接返回 address 能 work 只是因为你在 app component 里没用 onPush strategy ,默认在 UI event 后更新 component 的 view ,而 view 中使用了 address ,address push 了新值自然能在 view 中体现出来,和 signal 没关系,你就是写个普通 get 函数一样 work 。
chnwillliu
chnwillliu
319 天前
@Chad0000 这个 feature 就是前端大热的 signal ,就是为了做到细粒度更新 view 而引入的,将来可是要干掉 zonejs ,颠覆 Angular 自上而下 change detection 的。
Chad0000
Chad0000
318 天前
@chnwillliu
那它这么折腾侵入性太强了,反而不如 wpf 的实现优雅了。后者实现接口通知属性变更就行,我在实际使用过程中是偷懒反射然后动态触发通知,也算简洁和入侵不强。
Mirachael
Mirachael
318 天前
@wunonglin #19

试过了,不是设置 true ,应该时设置为 false ,确实可以更新视图

```

user = signal<User>({} as User, {
equal: () => false,
});
```
Mirachael
Mirachael
318 天前
@chnwillliu #21 shallow clone 确实可以,但是实际情况时 object 通常是带有方法的类实例,浅拷贝会导致 user signal 丢失方法。所以这种情况应该 deepClone
wunonglin
wunonglin
318 天前
@Mirachael #24 对,这里我写反了我勘误。但是你直接把 addresses 设置为 signal 不就好了吗
chnwillliu
chnwillliu
318 天前
@Mirachael 可以了解下 ngrx 的 singal store 和 deep signal 的概念哦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1033320

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX