繁体   English   中英

如何在 Ember Octane 中更新嵌套状态

[英]How to update nested state in Ember Octane

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

  @service('contact-data') contact;

每个字段代表一个通过访问的属性

{{contact.properties.foo}}

我将属性保存为 JS 对象,以便在使用它们时轻松过滤掉空字段,并使用@tracked跟踪它, @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. 如果对象真的像哈希映射一样使用,那么您有两个变体选项:
    1. 如果不需要 IE11 支持,请使用https://github.com/pzuraq/tracked-built-ins
    2. 做一个“纯功能更新”,在那里你做这样的事情this.properties = { ...this.properties, foo: newValue };

其中,(1) 几乎总是最便宜且性能最好的。 做 (2.1) 会有点贵,因为它需要使用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 updateFoo(newValue) {
    this.properties.foo = newValue;
  }

  @action updateBar(newValue) {
    this.properties.bar = newValue;
  }
}

请注意, @tracked 安装 getter 和 setter 代替普通类属性,因此如果您需要将其用于某处或类似地方的 JSON 有效负载,您还需要在实用程序类上实现toJSON

class TheProperties {
  @tracked id;
  @tracked foo;
  @tracked bar;
  
  toJSON() {
    let { id, foo, bar } = this;
    return { id, foo, bar };
  }
}

还有另一个附加组件对数组和对象的作用与跟踪内置函数基本相同。

它是一个代理,基本上通知根某处发生了更新。 与跟踪内置函数相比的优势在于,嵌套深度不受限制,因为 JSON 具有深度嵌套是很常见的。

在性能方面,缺点类似于内置跟踪。 谨慎使用它并尽量不要在具有数百/数千行的表中使用它,因为重新渲染将没有性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM