Ng-lazyload-image: Lazyloading gambar untuk url yang belum siap?

Dibuat pada 23 Mar 2017  ·  13Komentar  ·  Sumber: tjoskar/ng-lazyload-image

Hai,
Mencintai paket pertama!

Saya ingin bertanya apakah mungkin untuk memuat gambar dengan malas untuk url yang belum dibuat. Misalnya, saya memiliki pengguna yang mengirimkan sesuatu, tetapi URL statis yang menyajikan gambar belum siap ( GET 404 error ).

Apakah ada kemungkinan untuk memuat/menampilkan gambar gambar-gambar itu ketika url sudah siap. Mungkin dengan menampilkan defaultImage/errorImage hingga gambar yang dimuat lambat berfungsi?

help wanted

Semua 13 komentar

Hai,

Arahan saat ini tidak mendukung untuk memuat ulang gambar ketika url berubah (menjadi siap), namun saya akan menerima permintaan tarik untuk itu :)

Apa yang dapat Anda lakukan sementara itu adalah sesuatu seperti ini:

<img *ngIf="image" [lazyLoad]="image">

atau jika Anda memiliki gambar default:

<img *ngIf="!image" [src]="defaultImage">
<img *ngIf="image" [lazyLoad]="image" [defaultImage]="defaultImage">

Saya hanya mencari fungsi yang sama persis :/
url yang tidak segera tersedia ... perlu polling

@donjae apakah Anda pernah menemukan solusi? tulis sendiri?

@tjoskar mencoba

<img *ngIf="!image" [src]="defaultImage">
<img *ngIf="image" [lazyLoad]="image" [defaultImage]="defaultImage">

tidak berhasil, karena mungkin perlu waktu hingga 10 detik agar gambar saya tersedia di server

Adapun aplikasi saya, saya sebenarnya hanya menetapkan [errorImage] sebagai default untuk saat ini :/

hmm oke tks :/

@donjae
Ahhh... Saya pikir saya salah paham.
Anda memiliki URL ke gambar yang mengembalikan 404 untuk beberapa alasan dan Anda ingin melakukan polling untuk perubahan? Jadi jika perpustakaan tidak berhasil mengambil gambar, Anda ingin perpustakaan mencoba lagi, katakanlah 2 detik?
Saya tidak berpikir itu adalah sesuatu yang ingin saya dukung (atau mungkin saya akan, jika Anda dapat menemukan sesuatu yang pintar di: https://github.com/tjoskar/ng-lazyload-image/blob/d4b3d71f918b83aa18c5d4f7819e92cd2630bd1a/src /lazyload-image.ts#L79 dengan retryWhen ).

Saya pikir solusi yang lebih baik adalah membuat scroll-event-emitter Anda sendiri yang memancarkan nilai baru ketika gambar tersedia.

baiklah!

Saya akhirnya mengembangkan milik saya sendiri karena saya tidak membutuhkan pengguliran,
ini dia:

import {Directive, ElementRef, EventEmitter, Input, NgZone, Output} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {Subject} from "rxjs/Subject";

@Directive({
    selector: '[lazyImage]'
})
export class LazyImage {

    private m_url;
    private cancel$ = new Subject();

    constructor(private el: ElementRef, private ngZone: NgZone) {
    }

    @Input() defaultImage: string;
    @Input() loadingImage: string;
    @Input() errorImage: string;
    @Input() retry: number = 10;
    @Input() delay: number = 500;


    @Input()
    set url(i_url: string) {
        this.m_url = i_url;
        this.loadImage(i_url);
    }

    @Output() loaded: EventEmitter<any> = new EventEmitter<any>();
    @Output() completed: EventEmitter<any> = new EventEmitter<any>();
    @Output() errored: EventEmitter<any> = new EventEmitter<any>();

    set setUrl(i_url) {
        this.m_url = i_url;
        this.loadImage(i_url);
    }

    public resetToDefault() {
        this.setImage(this.el.nativeElement, this.defaultImage);
        this.cancel$.next({})
    }

    ngAfterViewInit() {
        this.setImage(this.el.nativeElement, this.defaultImage);
    }

    ngOnInit() {
    }

    setImage(element: HTMLElement, i_url) {
        // const isImgNode = element.nodeName.toLowerCase() === 'img';
        // if (isImgNode) {
        // } else {
        //     element.style.backgroundImage = `url('${imagePath}')`;
        // }
        (<HTMLImageElement>element).src = i_url;
        return element;
    }

    loadImage(i_url) {
        const pollAPI$ = Observable.defer(() => {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.src = i_url;
                img.onload = () => {
                    resolve(i_url);
                };
                img.onerror = err => {
                    this.setImage(this.el.nativeElement, this.loadingImage);
                    reject(err)
                };
            })


        }).retryWhen(err => {

            return err.scan((errorCount, err) => {
                if (errorCount >= this.retry) {
                    throw err;
                }
                return errorCount + 1;
            }, 0).delay(this.delay);
        }).takeUntil(this.cancel$)

        pollAPI$.subscribe((v) => {
            this.setImage(this.el.nativeElement, this.m_url)
            this.loaded.emit();
        }, (e) => {
            this.setImage(this.el.nativeElement, this.errorImage);
            this.errored.emit();
            // console.error(e)
        }, () => {
            this.completed.emit();
        })

    }

    destroy() {
    }
}

dan untuk menggunakannya:

 <img lazyImage class="center-block" style="width: 229px; height: 130px"
     [loadingImage]="'https://secure.digitalsignage.com/studioweb/assets/screen_loading.png'"
     [defaultImage]="'https://secure.digitalsignage.com/studioweb/assets/screen.png'"
    [errorImage]="'https://secure.digitalsignage.com/studioweb/assets/screen_error.png'"
    [retry]="5"
    [delay]="1500"
    (loaded)="_onLoaded()"
    (error)="_onError()"
    (completed)="_onCompleted()">

dan Anda juga dapat memuat gambar melalui API:

...

@ViewChild(LazyImage)
    lazyImage: LazyImage;
...

this.lazyImage.resetToDefault();
this.lazyImage.url = 'http://www.example.com/foo.png

@tjoskar apakah Anda ingin menggabungkan/menerapkan apa yang dibuat oleh @born2net ? tidak masalah jika tidak, dan saya dapat menyelesaikan masalah ini

(maaf karena terlambat membalas)
@donjae , saya mungkin tidak akan menerapkan ini tetapi saya akan menerima permintaan tarik.
Saya kira itu mungkin untuk mengganti baris 73 dengan sesuatu seperti:

.mergeMap(() => {
  return loadImage(imagePath)
    .retryWhen(errors => {
        return errors.scan((errorCount, err) => {
            if(errorCount >= 5) {
                throw err;
            }
            return errorCount + 1;
        }, 0)
      .delay(1000);
    })
})

Saya akan menutup masalah ini tetapi saya masih akan menerima permintaan tarik jika seseorang ingin menerapkannya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat