簡體   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