lukasz-galka / ngx-gallery

Angular image gallery plugin
https://lukasz-galka.github.io/ngx-gallery-demo/
MIT License
436 stars 172 forks source link

Dynamically change images and then call the method openPreview but report error #213

Open stringhuang opened 5 years ago

stringhuang commented 5 years ago

Hi,

Firstly, I mark down ngx-gallery component in html like below, while the variable galleryImages is empty. <ngx-gallery [images]="galleryImagesList" [options]="galleryOptions" #onlyPreviewGalleryHtml></ngx-gallery>

The variable galleryImage and others is defined in typescript file as : public galleryImagesList: NgxGalleryImage[] = new Array<NgxGalleryImage>(); public galleryOptions: NgxGalleryOptions[] = new Array<NgxGalleryOptions>(); @ViewChild('onlyPreviewGalleryHtml') public onlyPreviewGallery: NgxGalleryComponent; ngOnInit(): void { this.galleryOptions.push( { image: false, thumbnails: false, width: '0px', height: '0px' }, { image: false, thumbnails: false, width: '0px', height: '0px', previewZoom: true, previewRotate: true, previewCloseOnClick: true, previewCloseOnEsc: true, previewFullscreen: true, previewKeyboardNavigation: true, previewDescription: true, }, ); }

Secondly, I mark down one button in html, <button (click)="openPreview()">open preview and the function openPreview is defined as :

openPreview(): void { this.galleryImagesList.push({ small: 'assets/tmp/img/1.png', medium: 'assets/tmp/img/1.png', big: 'assets/tmp/img/1.png', }); this.galleryImagesList.push({ small: 'assets/tmp/img/2.png', medium: 'assets/tmp/img/2.png', big: 'assets/tmp/img/2.png', });

console.log(this.onlyPreviewGallery.images);

this.onlyPreviewGallery.openPreview(0);

}

so that, you may see I just want to dynamic set the gallery's images, however, when I first click the button, it report error as below, while you can see the images list is correct.

image

And then I click the button again ,it now worked ! image

so it is quite strange !

stringhuang commented 5 years ago

Hi,

I found that if I add below code into the method openPreview, it will not prompt error.

this.onlyPreviewGallery.bigImages[0] = 'assets/tmp/img/1.png';

it seems that directly set the images will not change the bigImages.

is that the case ?

rysal32 commented 5 years ago

Hi, was this issue fixed coz I have the same problem :(

hpawe01 commented 5 years ago

@stringhuang: Sometimes pushing into an existing array behaves weird. Have you tried setting the array in your openPreview method like this?

this.galleryImagesList = [{
    // image1
  }, {
    // image2
  }];

And can you please try to format your code expamples. Would be way easier to read.

Some other code remarks:

So you could shorten this: public galleryImagesList: NgxGalleryImage[] = new Array<NgxGalleryImage>(); to this: galleryImagesList: NgxGalleryImage[] = [];

asiena commented 5 years ago

Hey all, I didn't see any real solutions or work-arounds to this issue posted, so here's mine, with my opinion on why this is happening if someone wants to fix (wish I had the time). So basically, it seems that the NgxGalleryComponentis detached from the NgxGalleryPreviewComponent, which is the actual component that contains the array of image urls to render, as well as the description array. It seems that NgxGalleryPreviewComponent.prototype._show is called before these detached images/descriptions arrays can be updated by the main component. You can access this array directly as shown in the work-around below:

    openGallery(filter: any, index: number) {
        try {
            let pagesToView = [ 'assets/1-small.jpg', 'assets/2-small.jpg', 'assets/3-small.jpg' ];
            this.ngxImageGallery.images = [];
            for (let i = 0; i < pagesToView.length; i++) {
                this.ngxImageGallery.images.push({
                    small: pagesToView[i],
                    medium: pagesToView[i],
                    big: pagesToView[i],
                    description: '',
                    url: pagesToView[i]
                });
            }
            this.ngxImageGallery.preview.images = [];
            for (let i = 0; i < pagesToView.length; i++) {
                this.ngxImageGallery.preview.images.push(pagesToView[i]);
            }
            this.ngxImageGallery.preview.descriptions = [];
            for (let i = 0; i < pagesToView.length; i++) {
                this.ngxImageGallery.preview.descriptions.push('');
            }
            this.ngxImageGallery.openPreview(index);
        } catch (error) {
            abp.notify.error(error);
        }
    }

One more thing. There also appears to be an issue with NgxGalleryPreviewComponent.images having the type declaration of images: string[] | SafeResourceUrl[]; So I removed the | SafeResourceUrl[] part. If anyone has a better idea, please let me know.

Gurezkiy commented 4 years ago

Use ChangeDetectorRef before calling openPreview. Example:

@ViewChild('gallery', {static: false}) gallery: NgxGalleryComponent;

constructor(private changeDetectorRefs: ChangeDetectorRef) {
    //******
}

view (url) {
    this.gallery.images = [
      {
        small: url,
        medium: url,
        big: url
      }
    ];
    this.changeDetectorRefs.detectChanges();
    this.gallery.openPreview(0);
}