ember.js - 如何在 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) 会稍微贵一点,因为它需要使用 a Proxy
,但还不够你通常会注意到的。执行 (2.2) 最终会触发应用程序中任何地方使用的每个属性的重新渲染properties
,即使它没有更改。
在您描述的情况下,这些字段似乎是众所周知的,这意味着您应该使用该类。解决方案可能如下所示:
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 updateProperty(name, value) {
this.properties[name] = value;
}
}
请注意,@tracked
安装 getter 和 setter 代替普通类属性,因此如果您需要在某处或类似的地方将其用于 JSON 有效负载,您还需要toJSON
在实用程序类上实现:
class TheProperties {
@tracked id;
@tracked foo;
@tracked bar;
toJSON() {
let { id, foo, bar } = this;
return { id, foo, bar };
}
}
推荐阅读
- bash - 从 Windows 在某个目录中启动 bash
- postgresql - PostgreSQL / PostGIS 在查询中使用变量
- python-2.7 - 无法获得代表
- javafx - JavaFX setOnKeyReleased vs textProperty 监听器
- php - 通过一个按钮在浏览器中查看我的 PHP 源代码
- c++ - Qt Creator 和 Qt 桌面应用程序的菜单不可见或丢失
- javascript - .NET Core 2.1 使用 React 模板 - 使用“fetch()”时位置 0 处的意外令牌 < json
- javascript - Javascirpt:未捕获的 TypeError:对象不是函数 HTMLButtonElement.onclick
- java - 谷歌登录不会改变活动
- docker - 我无法将 docker 的文件系统挂载到主机的文件系统