即使您在 `ember-typescript-cli` 中使用 `YourModel.create({…})` 也无法读取 null 的 属性 ‘setDirtyAttribute’

`cannot read property ‘setDirtyAttribute’ of null` even if you use `YourModel.create({…})` in `ember-typescript-cli`

面对cannot read property 'setDirtyAttribute' of null即使你在ember-typescript-cli中使用YourModel.create({...})创建一个EmberObject。

型号:

import DS from 'ember-data';
import {computed} from "@ember/object";

export default class Person extends DS.Model {
  @DS.attr() firstName!: string;
  @DS.attr() lastName!: string;
  @DS.attr() age!: number;
  @DS.attr() desc?: string;


  @computed("firstName", "lastName")
  public get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

路线:

export default class Persons extends Route {
  @service() public store!: DS.Store;

  constructor() {
    super(...arguments);

    const persons: Person[] = [
      Person.create({firstName: "first1", lastName: "last1", age: 10}),
      Person.create({firstName: "first2", lastName: "last2", age: 320}),
      Person.create({firstName: "first3", lastName: "last3", age: 30}),
    ];
      persons.forEach(p => this.store.createRecord('person', p));
  }
}

进入页面报错:

Uncaught TypeError: Cannot read property 'setDirtyAttribute' of null
    at Person.set (-private.js:144)
    at ComputedProperty._set (metal.js:3543)
    at ComputedProperty.setWithSuspend (metal.js:3532)
    at ComputedProperty.set (metal.js:3503)
    at initialize (core_object.js:67)
    at Function.create (core_object.js:692)
    at new Persons (persons.js:23)
    at Function.create (core_object.js:684)
    at FactoryManager.create (container.js:549)
    at instantiateFactory (container.js:359)

所以我必须使用 this.store.createRecord('person', {firstName: "first1", lastName: "last1", age: 10}) 而不是 this.store.createRecord('person', <a Person class instance>) 之类的东西,这根本不是打字稿。所以我希望找到一种更优雅的方式将 ember 特性结合到打字稿中,而不是到处使用 any 或裸露的 object

有什么建议吗?

Ember 数据的文档非常清楚你不应该使用 Model.create({})。它不仅是私有的 API,甚至还记录了模型的实例只能使用商店服务创建:

Create should only ever be called by the store. To create an instance of a Model in a dirty state use store.createRecord.

To create instances of Model in a clean state, use store.push

https://api.emberjs.com/ember-data/3.11/classes/Model/methods/create?anchor=create&show=inherited%2Cprotected%2Cprivate

默认情况下,

Ember 数据的 public API 应该可以很好地与 Typescript 配合使用。 ember-data@3.11.0 中的 known and documented bug 应该在以后的小版本中得到修复。

请参阅Ember CLI TypeScript's documentation about Ember Data support了解支持的设置。