Аурелия: Как обработать асинхронный запрос в представлении?

У меня есть 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 }">  
Другие вопросы по тегам