Angular2: How to handle a async image (blob) reque

2019-04-07 08:48发布

I am trying to request a image via a secured api. At the moment I got the following to work (see all the resources I use below.

import { AssetsService } from '../../services/AssetsService';
import { Component } from '@angular/core';

@Component({
    templateUrl: 'home.html',
})
export class HomePage {

    public img;

    constructor(
        public assets_service: AssetsService
    ) { }

    public async ionViewDidEnter() {
        this.img = await this.assets_service.picture_request('test.png');
    }
}

My view

<img [src]="img | safe" />

Now I've seen the async pipe that looks promising. As you might have guessed, I really don't want to use a viewmodel property for each of the image I want to request via the api like used above.

I want to to use the async call picture_request straight from the html view. That will save me all the plumbing in the viewmodel. From what I've read somethings like something like this should work, but only it doesnt sadly.

<img [src]="assets_service.picture_request('test.png') | async | safe" />

I am not sure if I am using the async pipe correctly or using the right approach. If I'm not what should my approach be? Any help is appreciated. FYI: I am using angular 2 in combination with ionic 2.

My other used resources:

My Safe pipe

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
    constructor(
        private sanitizer: DomSanitizer
    ) { }
    transform(url) {
        return this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
} 

My assets service

import 'rxjs/Rx';
import { Headers, RequestOptions, ResponseContentType } from '@angular/http';
import { Injectable } from '@angular/core';
import { AppConfiguration } from '../app/AppConfiguration';
import { AuthHttp } from 'angular2-jwt';

@Injectable()
export class AssetsService {

    constructor(
        private auth_http: AuthHttp
    ) { }

    /**
     * Fetches a image by filename by filename and converts it to a blob/object url
     */ 
    public picture_request(filename: string) {
        return this.auth_http.post(AppConfiguration.base_url + 'assets/image',
            JSON.stringify({
                filename: filename
            }), 
            new RequestOptions({
                responseType: ResponseContentType.Blob,
                headers: new Headers({
                    'Content-Type': 'application/x-www-form-urlencoded'
                })
            })
            .map(res => res.blob())
            .map(blob => URL.createObjectURL(blob))
            .toPromise();
    }
}

1条回答
We Are One
2楼-- · 2019-04-07 09:18

I've found a solution which worked for me. I created a custom component.

import { Component, Input } from '@angular/core';
import { AssetsService } from '../../services/AssetsService';

@Component({
    selector: 'async-image',
    template: `<img [src]="img | safe" />`
})
export class AsyncImageComponent {

    @Input() filename: string;
    public img: any;

    constructor(
        public assets_service: AssetsService
    ) { }

    public async ngOnInit(): Promise<void> {
       this.img = await this.assets_service.picture_request(this.filename);
    }
}

Which I can use like this.

<async-image filename="{{image.filename}}"></async-image>
查看更多
登录 后发表回答