[英]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 的get
和set
函數時。 具體來說,Ember 的類型試圖確保您在執行get
和set
時不會打錯字。 您可以在此示例中看到為什么它們不允許任意字符串:
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.