如何解决 defineProperty 弃用错误?

How can I resolve the defineProperty deprecation error?

我收到一个名为 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/defineProperty

请举例说明如何解决它,我有点困惑。

这是我的代码

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;
  }
});

非常感谢任何回复。

问题出在init-method中的if-else-statement。您想要动态定义计算的 属性 "value"。这已被弃用!

在 Ember 3.2 中添加了折旧。该代码在 3.5 之前有效。官方解释如下:

Although uncommon, it is possible to assign computed properties directly to objects and have them be implicitly computed from eg Ember.get. As part of supporting ES5 getter computed properties, assigning computed properties directly is deprecated. You should replace these assignments with calls to 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"

的动态创建
  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;
    }
  }),
  ....