如何解决如何在Ember Octane中更新嵌套状态
所以我的情况如下: 我有一个带有几个输入字段的组件,这些输入字段表示一个联系人,并填充了服务中的数据:
@service('contact-data') contact;
每个字段代表一个可通过
访问的属性{{contact.properties.foo}}
我将属性另存为JS对象,以便在使用它们时轻松过滤出空字段,并使用@tracked
对其进行跟踪,如下所示:
export default class MyService extends Service {
@tracked properties = {id: 0,foo: "",bar : "abc",};
@action updateProperty(name,value) {
this.properties[name] = value;
}
}
但是,属性无法在组件中正确重新呈现,并且文本字段也无法更新。
对此我将不胜感激!谢谢!
解决方法
每当您遇到一堆需要跟踪的嵌套状态时,仅跟踪顶层对象都不会导致对该对象内部的更新传播出去。您需要跟踪内部属性,或者或您需要重置要跟踪的整个对象。
对于处理这些内部属性的更新,基本上有两个粗略的选择:
- 如果对象的形状众所周知,则将其提取到在字段上使用
@tracked
的实用程序类中,并在创建服务时实例化该实用程序类。然后这些字段的更新将更新。 - 如果确实像哈希图一样使用该对象,则有两个变体选项:
- 如果不需要IE11支持,请使用https://github.com/pzuraq/tracked-built-ins
- 进行“纯功能更新”,在此过程中,您将执行类似
this.properties = { ...this.properties,foo: newValue };
的操作
其中,(1)几乎总是最便宜且性能最佳。这样做(2.1)会稍微贵一点,因为它需要使用Proxy
,但通常您不会注意到。执行(2.2)最终将触发应用程序中任何地方使用的properties
中的 every 属性的重新渲染,即使它没有更改。
在您描述的情况下,似乎这些字段是众所周知的,这意味着您应该接触该课程。解决方案可能看起来像这样:
import Service from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
class TheProperties {
@tracked id;
@tracked foo;
@tracked bar;
}
export default class MyService extends Service {
properties = new TheProperties();
@action updateFoo(newValue) {
this.properties.foo = newValue;
}
@action updateBar(newValue) {
this.properties.bar = newValue;
}
}
请注意,@tracked
installs getters and setters in place of plain class properties,因此,如果您需要在某处或类似地方将它用于JSON有效负载,则还需要在实用程序类上实现toJSON
:>
class TheProperties {
@tracked id;
@tracked foo;
@tracked bar;
toJSON() {
let { id,foo,bar } = this;
return { id,bar };
}
}
,
还有另一个 add-on 对数组和对象的作用与跟踪内置函数基本相同。
它是一个代理,基本上通知根某处发生了更新。与跟踪内置函数相比的优势在于,嵌套深度不受限制,因为 JSON 具有深度嵌套是很常见的。
就性能而言,缺点类似于内置跟踪。谨慎使用它,并尽量不要在具有数百/数千行的表中使用它,因为重新渲染将没有性能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。