Ember JS-如何在渲染之前等待异步函数响应

时间:2019-11-21 12:18:18

标签: javascript ember.js handlebars.js ember-data

我目前正在从事通过外包媒介提供给公司的项目。我的问题是关于渲染图像src。

以前,他们提供文件系统中的图像。我们现在不再合并使用AWS S3存储桶服务,因此不再需要使用该方法。我们还使用Cloudfront缓存,因此我们希望能够将URL从后端发送到前端(我们这样做),然后呈现图像。

在模型中,我有一个从后端检索图像URL并将其返回的函数,但是在渲染过程中,图像src被设置为[object Object]我认为这是在将src设置为函数,而不是响应。

这是我们在其中呈现的功能,用于获取网址

baseUrl: Ember.computed(async function () {
let adapter = this.store.adapterFor('article-image');
let ajax = this.get('ajax');

let path = ''

let API_URL = `${adapter.buildURL('article-image', this.id)}/original/${this.get('fileName')}`;
let promise = new Promise((resolve, reject) => {
  ajax.request(API_URL, {
    method: 'GET'
  })
    .then(function (response) {
      resolve(response.path);
    })
    .catch(function (err) {
      console.log('error');
      console.log(err);
    });
})
path = await promise
return path;
}),

这是我们称为image.baseUrl的位置,其中src设置为[object Object]

{{lazy-image
url=(concat image.baseUrl)
alt=(if title title (if image.title image.title 'Image'))
class=(if class class 'img-responsive')}}

1 个答案:

答案 0 :(得分:3)

在这里,您是从计算所得的属性(它是一个对象而不是字符串)中返回一个Promise。

通常,在渲染您的组件之前,我们实际上并不等待承诺解决。相反,我们先渲染某些东西(例如加载的gif),然后在解决诺言后重新渲染图像。

对此问题有两种传统的解决方案。一种是在您的计算属性中使用PromiseProxy。

return Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({ promise });

您可以在模板中使用如下代码:

{{#if image.baseUrl.isPending}}
  <img src="loading.gif">
{{else}}
  {{lazy-image url=(concat image.baseUrl.content) ...}}
{{/if}}

请参见https://api.emberjs.com/ember/release/classes/PromiseProxyMixin

第二种传统解决方案是使用ember-concurrency并避免返回promise的计算属性。这涉及到必须重新编写代码。

请参见http://ember-concurrency.com/docs/introduction/

我通常更喜欢此解决方案,因为使用承诺代理可能会变得复杂且难以理解。

此外,如果您使用的是Ember的较新版本(2.10或更高版本),则可以尝试使用ember-lifeline,与ember-concurrency相比,添加到项目中的代码要少得多,满足此需求的更简单的api。 (根据您的代码示例,我假设您使用的是Ember的较早版本,但使用的是现代浏览器。)请参见https://ember-lifeline.github.io/ember-lifeline/