首页 > 解决方案 > 如何解决 defineProperty 弃用错误?

问题描述

我收到一个错误DEPRECATION: [DEPRECATED] computed property 'value' was not set on object via 'defineProperty' [deprecation id: ember-meta.descriptor-on-object],我很确定它希望我解决哪个资源文件。但是,我看到了与我收到的有关弃用的文档,我发现了这个

https://deprecations-app-prod.herokuapp.com/v3.x/#toc_use-defineProperty-to-define-computed-properties https://emberjs.com/api/ember/release/functions/@ember%2Fobject /定义属性

请给我一个关于如何解决它的例子,因为我有点困惑。

这是我的代码

import TextField from '@ember/component/text-field';
import { computed } from '@ember/object';
import { reads } from '@ember/object/computed';

import FormControlMixin from 'bos-web/mixins/components/form/control';
import InFormGroupMixin from 'bos-web/mixins/components/form/in-form-group';

/**
 * @protected
 * @component
 * @class TextFormControl
 * @extends Ember.TextField
 * @mixes FormControlMixin
 * @mixes InFormGroupMixin
 */
export default TextField.extend(FormControlMixin, InFormGroupMixin, {
  /**
   * @public
   * @override
   * @property autocomplete
   * @type {string}
   */
  autocomplete: 'off',

  /**
   * @public
   * @override
   * @property classNameBindings
   * @type {string|Array<string>}
   */
  classNameBindings: ['textAlign', 'controlExtraClassNames'],
  /**
   * @public
   * @computed
   * @property textAlign
   * @type {string}
   */
  textAlign: computed('formGroup.textAlign', function() {
    let textAlign = this.get('formGroup.textAlign');

    switch (textAlign) {
      case 'right':
      case 'center':
        return `text-${textAlign}`;
      default:
        return '';
    }
  }),
  /**
   * @public
   * @computed
   * @property controlExtraClassNames
   * @type {Array}
   */
  controlExtraClassNames: reads('formGroup.controlExtraClassNames'),

  /**
   * @public
   * @computed
   * @property placeholder
   * @type {string}
   */
  placeholder: reads('formGroup.placeholder'),
  /**
   * @public
   * @computed
   * @property name
   * @type {string}
   */
  name: reads('formGroup.name'),
  /**
   * @public
   * @computed
   * @property required
   * @type {boolean}
   */
  required: reads('formGroup.required'),
  /**
   * @public
   * @computed
   * @property disabled
   * @type {boolean}
   */
  disabled: reads('formGroup.disabled'),
  /**
   * @public
   * @computed
   * @property autofocus
   * @type {boolean}
   */
  autofocus: reads('formGroup.autofocus'),
  /**
   * @public
   * @computed
   * @property type
   * @type {string}
   */
  type: reads('formGroup.type'),
  /**
   * @public
   * @computed
   * @property maxlength
   * @type {number}
   */
  maxlength: reads('formGroup.maxLength'),
  /**
   * @public
   * @computed
   * @property synchroniseOnReturn
   * @type {boolean}
   */
  synchroniseOnReturn: reads('formGroup.synchroniseOnReturn'),
  /**
   * @public
   * @computed
   * @property value
   * @type {string}
   */
  value: undefined,

  /**
   * @public
   * @override
   * @hook
   * @method init
   */
  init() {
    this._super();

    if (this.get('synchroniseOnReturn')) {
      this.value = computed('formGroup.value', {
        get() {
          return this.get('formGroup.value');
        },
        set(_, value) {
          value = this.trimValue(value);
          this.set('_value', value);

          return value;
        }
      });
    } else {
      this.value = computed('formGroup.value', {
        get() {
          return this.get('formGroup.value');
        },
        set(_, value) {
          value = this.trimValue(value);
          this.setFormGroupValue(value);

          return value;
        }
      });
    }
  },

  /**
   * @public
   * @method keyDown
   * @param {JQueryEven} e
   * @return {boolean} whether bubbling
   */
  keyDown(e) {
    if (this.get('synchroniseOnReturn') && e.keyCode === 27) {
      e.stopPropagation();

      this.set('value', this.get('formGroup.value'));

      return false;
    }
  },

  /**
   * @public
   * @method keyPress
   * @param {JQueryEvent} e
   * @return {boolean} whether bubbling
   */
  keyPress(e) {
    if (this.get('synchroniseOnReturn') && e.keyCode === 13) {
      e.stopPropagation();

      let value = this.get('_value');

      value = this.trimValue(value);
      this.setFormGroupValue(value);

      return false;
    }
  },

  /**
   * @public
   * @method focusIn
   * @param {JQueryEvent} e
   */
  focusIn(/*e*/) {
    this.$().select();
  },

  /**
   * @public
   * @method focusOut
   * @param {JQueryEvent} e
   */
  focusOut() {
    let synchroniseOnReturn = this.get('synchroniseOnReturn');
    let formGroupValue = this.get('formGroup.value');

    if (synchroniseOnReturn && this.get('_value') !== formGroupValue) {
      this.set('value', formGroupValue);
    }
  },

  /**
   * @public
   * @method change
   * @param {JQueryEvent} e
   */
  change() {
    let formGroup = this.get('formGroup');

    formGroup.sendAction('onChange', formGroup.get('model'));

    return true;
  }
});

任何回应都非常感谢。

标签: ember.jsember-dataember-cli

解决方案


问题在于 init-method 的 if-else-statement。您想动态定义计算属性“值”。这已被弃用!

Ember 3.2 中添加了折旧。该代码工作到 3.5。以下是官方解释:

虽然不常见,但可以将计算属性直接分配给对象并让它们从例如Ember.get中隐式计算。作为支持 ES5 getter 计算属性的一部分,不推荐直接分配计算属性。您应该将这些分配替换为对defineProperty的调用

因此,在我看来,您有两种选择来解决弃用问题:

1. 使用来自@ember/object 的defineProperty

import { defineProperty } from '@ember/object';
...
if (this.get('synchroniseOnReturn')) {
  defineProperty(this, 'value', computed('formGroup.value', {
    get() {
      return this.get("formGroup.value");
    },
    set(_, value) {
      value = this.trimValue(value);
      this.set("_value", value);

      return value;
    }
  }));
} else {
  ...
}

2.重构您的代码并删除计算属性“值”的动态创建

  value: computed('formGroup.value', {
    get() {
      return this.get("formGroup.value");
    },
    set(_, value) {
      value = this.trimValue(value);
      if (this.get("synchroniseOnReturn")) {
        this.set("_value", value);
      }
      else {
        this.setFormGroupValue(value);
      }

      return value;
    }
  }),
  ....

推荐阅读