gpt4 book ai didi

ember.js - 如何在 Ember Octane 中更新嵌套状态

转载 作者:行者123 更新时间:2023-12-02 06:06:26 25 4
gpt4 key购买 nike

所以我的情况如下:我得到了一个包含几个输入字段的组件,这些字段代表一个联系人并填充了来自服务的数据:

  @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;
}
}

但是,属性不会在组件中正确重新呈现,并且文本字段不会得到更新。

如果有任何帮助,我将不胜感激!谢谢!

最佳答案

任何时候你有一堆嵌套状态需要跟踪,只跟踪顶级对象不会导致该对象内部的更新传播出去。您需要跟踪内部属性,您需要重置您正在跟踪的整个对象。

您基本上有两个粗略的选择来处理这些内部属性的更新:

  1. 如果对象具有众所周知的形状,请将其提取到在字段上使用 @tracked 的实用程序类中,并在创建服务时实例化实用程序类。然后这些字段的更新也会更新。
  2. 如果对象真的像 HashMap 一样被使用,那么您有两个变体选项:
    1. 使用 https://github.com/pzuraq/tracked-built-ins , 如果你不需要 IE11 支持
    2. 执行“纯功能更新”,您可以在其中执行类似 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 updateProperty(name, value) {
this.properties[name] = value;
}
}

注意 @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, foo, bar };
}
}

关于ember.js - 如何在 Ember Octane 中更新嵌套状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64267670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com