繁体   English   中英

emberjs glimmer object set() 与变量属性名称

[英]emberjs glimmer object set() with variable property name

我在 Ember 3.15 中有一个组件,我正在尝试做类似的事情

import { action, set } from '@ember/object';

@action
someMethod() {
  const value = ... // something random
  let propertyName = ... // some variable string
  set(this, propertyName, value);
}

它似乎在浏览器中运行良好,但 typescript 将设置行标记为错误(特别是 propertyName 参数)。 那么如果有效,为什么 typescript 不喜欢呢?

这似乎也发生在 get() 中,它不喜欢像get(this, propertyName)这样的变量 propertyNames 。

一般来说,如果你的属性是@tracked ,你不需要set ,只需这样做this[propertyName] = value; .

但是,您的问题可能是一般的 typescript 限制。 static打字的一个普遍问题:

Typescript 只做 static 分析。 所以它不会执行你的代码。 所以它无法知道动态生成的属性键是否真的存在。

所以如果你有这样的事情:

class Foo {
  data1: number = 1;
  data2: number = 2;
  foo() {
    const fixedProp = 'data1';
    console.log(this[fixedProp]);
    const dynamicProp = 'data' + (1 + 1);
    console.log(this[dynamicProp]);
  }
}

然后 typescript 将无法验证this[dynamicProp]是否确实存在,因为为此它需要执行'data' + (1 + 1); 所以它会知道dynamicProp实际上是什么。 所以通过 static 分析无法知道this[dynamicProp]是否存在。

您可以通过(this as any)[dynamicProp]告诉 typescript 做您想做的事情,它会忽略它。 但通常,如果您动态计算属性键,则不能依赖 static 分析。

您所描述的情况有两个基本问题 - 其中一个与 TypeScript 有关,其中一个与此无关。

TypeScript 的问题是 TS 通常知道属性的名称,并且会检查您是否正确设置了内容——无论是在使用普通 JS 属性查找和赋值时,还是在使用 Ember 的getset函数时。 具体来说,Ember 的类型试图确保您在执行getset时不会打错字。 您可以在此示例中看到为什么它们不允许任意字符串:

import Component from '@ember/component';
import { action, set } from '@ember/object';

export default class Whoops extends Component {
  greeting = 'Hello';

  @action updateGreeting(newGreeting) {
    set(this, 'greering', newGreeting);
    //         ----^--- TYPO!!!
  }
}

如果set (或get )的类型只允许任意字符串,那么 TS 在这里根本帮不了你; 它会让它成为 go,而且您必须自己找出错误 - 而不是编译器会帮助您提前告诉您。

在您遇到的情况下, TypeScript 可能只是看到一个字符串,它说“我没有任何方法可以检查这个字符串是否属于该属性。”

这里有几种改进方法。 首先,如果可以,您应该弄清楚是否可以将propertyName的类型限制为它来自的类型的keyof (解释keyof超出了这个答案的 scope , 手册中的这一部分这篇博文将让你快速上手。)

其次,与更大的问题有关:您在讨论该问题的另一个答案时指出,问题是您正试图在单个跟踪根 state 上深入设置属性。 通常,您应该以这种方式改变自动跟踪的 state - 这是 Ember Classic 使用其计算属性的旧观察者驱动模式的保留。 相反,更愿意通过 state 的所有者来驱动对自动跟踪的 state 的所有更改。 那么你根本不需要set ,系统会自动正确更新。

您可以通过为嵌套 state本身自动跟踪来做到这一点,方法是为其定义一个 class 或使用类似跟踪内置插件的东西来包装一个普通的 JS ZA8CFDE6331BD59EB2AC96F8911C4B666 无论哪种方式,与其从任何地方深入并深入变异 state,不如在拥有该 state 的 object 上执行此操作。 如果您遵循该模式,并将propertyName限制为keyof TheOwnerOfTheState的键,其中TheOwnerOfTheState是某个 class,那么在 Ember 端和 TypeScript 端,一切都将“正常工作”。

暂无
暂无

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

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