Аурелия: Как обработать асинхронный запрос в представлении?
У меня есть API-интерфейс ядра dotnet, который возвращает FileContentResult..
return new FileContentResult(bytes, contentType)
{
FileDownloadName = Path.GetFileName(request.Filename)
};
Через почтальона я могу отлично прочитать изображение. Теперь я хочу прочитать изображение через клиент aurelia fetch и показать его в моем html-виде. Это моя функция для извлечения изображения из API.
public image(filename: string) {
return this.http.fetch(AppConfiguration.base_url + 'assets/image',
{
method: 'post',
body: json({
filename: filename
})
});
}
Я попытался преобразовать BLOB-объект в ответ с помощью этого преобразователя значения. Но я не могу заставить это работать
Преобразователь:
export class BlobToUrlValueConverter {
public toView(blob) {
return URL.createObjectURL(blob);
}
}
ViewModel:
export class Dashboard {
public blob: any;
constructor(
public assets_service: AssetsService
) { }
async attached() {
let response = await this.assets_service.image('test.png');
this.blob = response.blob();
}
}
Посмотреть
<div if.bind="blob">
${ blob | blobToUrl }
</div>
Я не уверен, что это правильный подход. Также не уверен, как обработать часть асинхронного запроса. Каков наилучший способ отображения ответа на изображение в представлении html? Скажем через тег img?
1 ответ
Я был близко. Вот как я получил изображение, чтобы показать.
ViewModel:
export class Dashboard {
public url: string;
constructor(
public assets_service: AssetsService
) { }
async attached() {
let blob = await this.assets_service.image('test.png')
.then(response => response.blob());
this.url = URL.createObjectURL(blob);
}
}
Посмотреть:
<div if.bind="url">
<img src.bind="url">
</div>
РЕДАКТИРОВАТЬ:
Нашли лучшее решение, используя детали, написанные выше:
Экспортируемая функция, которая выполняет вызов (для повторного использования на сторонах ts и html):
export function image_request(filename: string): Promise<Response> {
let http = new Http();
return http.fetch(<your-url-that-fetches-the-image>,
{
method: 'post',
body: json({
filename: filename
})
});
}
Преобразователь значений, который использует вышеуказанную функцию
import { image_request } from './AssetsRequests';
export class ImageRequestValueConverter {
public toView(filename: string) {
return image_request(filename);
}
}
Важная и самая удивительная часть решения. Большое спасибо http://www.sobell.net/aurelia-async-bindings/ за то, что помогли мне. Вы можете изменить поведение привязки. Это переопределение можно использовать для обработки асинхронного Promise в представлении в сочетании с преобразователем значений.
export class AsyncImageBindingBehavior {
public bind(binding, source): void {
binding.originalupdateTarget = binding.updateTarget;
binding.updateTarget = (target) => {
// When we have a promise
if (typeof target.then === 'function') {
// Set temp value to loading so we know its loading
binding.originalupdateTarget('Loading...');
// Process the promise
target
.then(response => response.blob())
.then(blob => binding.originalupdateTarget(
URL.createObjectURL(blob)
));
}
else {
binding.originalupdateTarget(target);
}
};
}
unbind(binding) {
binding.updateTarget = binding.originalupdateTarget;
binding.originalupdateTarget = null;
}
}
Наконец вид очень прост
<img src="${ 'test.png' | imageRequest & asyncImage }">