如何为 'extend' 提供动态值? (或 'how does extend work in this case' ?)

How can I provide dynamic values for an 'extend'? (or 'how does extend work in this case' ?)

我在看 class (this one). The doco for it suggests you can extend the class to change a property of the class。没错,它对我有用。

但是我想做的是动态提供设置值。

我有两个问题。

第一个

如何调整 the demo 以便我可以动态提供所使用的值。

第二

我在查看 class 时意识到,这似乎是代码的重要部分...

  ajax (url, data = {}, method = this.method) {
    const ajaxSettings = assign(
      {},
      {
        contentType: false,
        processData: false,
        xhr: () => {
          const xhr = $.ajaxSettings.xhr();
          xhr.upload.onprogress = (event) => {
            this.didProgress(event);
          };
          this.one('isAborting', () => xhr.abort());
          return xhr;
        },
        url,
        data,
        method
      },
      get(this, 'ajaxSettings')
    );

    return this.ajaxPromise(ajaxSettings);
  },

...我不确定我是否理解 'extend' 是如何做它正在做的事情的。 ajaxSettingsajax 函数中使用,那么 extend 如何到达函数内部并将扩展中提供的值合并到函数中的硬编码值中?

希望这个问题是有道理的...如果你不写一本书就无法管理 'Second',我很乐意回答 'First' ;-)


回复评论

  1. 看起来你可以简单地使 ajaxSettings 成为一个计算的 属性 如果你想动态地设置它:
import Uploader from 'ember-uploader/uploaders/uploader';
import { computed } from '@ember/object';

export default Uploader.extend({
  ajaxSettings: computed('someProperty', function() {
    // do your logic to set the options dynamically in here
    return {
      headers: {
        'X-Application-Name': 'Uploader Test'
      }
    };
  })
});
  1. 这确实是使用 ajaxSettings 属性 的地方,关键代码行是这一行:
get(this, 'ajaxSettings')

从 class 中检索 ajaxSettings 属性(因此,如果 ajaxSettings 设置在基础 class 上,则您的子 class 将覆盖基础 class 设置——有关扩展的更多信息,请参阅 here

该行与 Object.assign() (technically Ember's polyfill) 结合使用来构建选项。这部分提供了一些默认值:

{
  contentType: false,
  processData: false,
  xhr: () => {
    const xhr = $.ajaxSettings.xhr();
    xhr.upload.onprogress = (event) => {
      this.didProgress(event);
    };
    this.one('isAborting', () => xhr.abort());
      return xhr;
    },
    url,
    data,
    method
  }
}

但由于 ajaxSettings 的检索发生在默认值之后,因此在您的 class' ajaxSettings 对象中指定的与上述默认值重叠的任何属性都将优先并覆盖它们。

因此,如果您在 class' ajaxSettings 中定义 contentType,如下所示:

ajaxSettings: computed('someProperty', function() {
  return {
    contentType: true, // (or some other value besides false)
    ...
  };
})

这将与上面默认值中指定的 contentType: false 重叠,并且由于它将在默认值之后通过 assign() 合并,因此优先。