【问题标题】:Can't add new property to subclass无法将新属性添加到子类
【发布时间】:2018-03-09 17:37:15
【问题描述】:

我基本上正在尝试为一个小项目编写一个自定义 ORM,并且我正在使用一个类来设置我的记录,默认情况下,所有记录都将通过一种类型检查器,该类型检查器将根据我的内容转换任何值说他们应该是

export default class Record {
  constructor(...props) {
    const [model, data] = props;
    forOwn(data, (value, key) => {
      if (model.hasOwnProperty(key)) {
        this[key] = attr(model[key], value);
      } else {
        this[key] = value;
      }
    });
  }
}

通过循环数据数组并从中创建新实例就可以正常工作

data.forEach((item) => {
  serializedData.push(new Item(model, item));
});

Item 只是一个简单的扩展类

class Item extends Record {
  constructor(...props) { super(...props); }
}

这是我遇到问题的地方,我想向Item 子类添加一个新的itemImage 属性,该子类将采用一些现有值并从中创建一个URL。

这两种方法我都试过了,我在网上搜索后发现的,但都不起作用

Reflect.defineProperty(Item.prototype, 'itemImage', {
  get() {
    return `//res.cloudinary.com/***/image/upload/${this.image.image_crop}/${this.image.image_version}/${this.auction_code}/${this.image.original_image_name}`;
  }
});

class Item extends Record {
  ...

  get itemImage() {
    return this.getItemImage();
  }
  getItemImage() {
    return `//res.cloudinary.com/***/image/upload/${this.image.image_crop}/${this.image.image_version}/${this.auction_code}/${this.image.original_image_name}`;
  }
}

我该怎么做呢?

编辑

attr 的作用如下

const attr = (type, data) => {
  switch (type) {
    case 'number':
      return parseFloat(data);
    case 'string':
      return data.toString();
    case 'object':
      if (typeof data === 'string' && data.indexOf('{') > -1) {
        return JSON.parse(data);
      } else {
        return data;
      }
  }
};

这是一个完整的沙盒,带有反应演示

https://codesandbox.io/s/7m388jwk1q

【问题讨论】:

  • 与您的问题无关,但仅供参考,您应该使用Object.defineProperty 而不是Reflect.defineProperty,否则如果设置属性失败,您可能会默默吞下错误。
  • attr() 在做什么?
  • 你能创建一个 jsfiddle 吗?
  • @JonasW。添加了attr() 函数引用。 @JoeWarner 添加了一个 jsfiddle 链接

标签: javascript ecmascript-6 es6-class


【解决方案1】:

您的问题与子类 getter 无关。问题在于您的数据格式。

看看image 属性:

"image": "[{\"original_image_name\":\"iqsnzsutgbpgqsztani5.png\",\"image_crop\":\"c_crop,h_450,w_1125\"}]"

当它被attr函数解析时,它变成了一个数组,不是一个对象。所以你不能访问这样的字段:${this.image.image_crop}

但是,如果您删除方括号,一切都会正常。或者,如果您无法更改数据格式,只需像这样访问图像:${this.image[0].image_crop}

【讨论】:

  • 所以它似乎有点工作,我可以控制台日志并在那里看到它但是当我尝试渲染到页面时(在我的情况下反应)我什么也看不到。不知道为什么,我尝试在末尾添加(),但它抱怨它不是一个函数,这是我所期望的
  • @Jordan 我尝试将 () 添加到末尾 - 到什么末尾?以及如何呈现页面?这涉及到哪些数据?如果您添加了一些有关您下一步要做什么的详细信息,那就太好了
  • 我用沙箱链接更新了原始问题,而不是 jsfiddle,我只在其中放入了相关代码和片段,并尝试将 itemImage 属性呈现到页面
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
相关资源
最近更新 更多