Ng-lazyload-image: Demande de fonctionnalité : accéder à l'image en création observable

Créé le 3 févr. 2018  ·  4Commentaires  ·  Source: tjoskar/ng-lazyload-image

Motivation et mise en œuvre

À l'heure actuelle, il est possible de passer un observable qui est un excellent moyen d'étendre la bibliothèque. Cependant, c'est un peu limité car les utilisateurs ne peuvent pas accéder à l'image de manière simple.

L'un des problèmes les plus courants est lorsque l'utilisateur n'utilise pas la fenêtre pour faire défiler ou utilise une bibliothèque en 3 parties qui ajoute des couches de défilement supplémentaires (par exemple, ionic, ng material design, etc.), et il peut parfois être difficile à trouver sur quel élément qui défile réellement. Une façon de résoudre ce problème pourrait être d'utiliser un Intersection Observer (qui peut également augmenter les performances). Par exemple.

@Component({
  selector: 'intersection-observer',
  template: `<img #img [defaultImage]="defaultImage" [lazyLoad]="image" [scrollObservable]="subject">`,
})
export class IntersectionObserverComponent {
  @ViewChild('img') img;
  subject = new Subject();
  defaultImage = 'https://www.placecage.com/1000/1000';
  image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';

  ngAfterViewInit() {
    const config = {
      rootMargin: '50px 50px',
      threshold: 0.01
    };

    function onIntersection(entries) {
      entries.forEach(entry => {
        if (entry.intersectionRatio > 0) {
          observer.unobserve(entry.target);
          this.subject.next();
        }
      });
    }
    const observer = new IntersectionObserver(onIntersection, config);
    observer.observe(this.img.nativeElement);
  }
}

Ceci est cependant assez lourd.

Ce que nous pouvons faire est d'accepter une fonction comme scrollObservable , quelque chose comme :

if (!this.scrollObservable) {
  const windowTarget = isWindowDefined() ? window : undefined;
  scrollObservable = getScrollListener(this.scrollTarget || windowTarget);
} else if (typeof this.scrollObservable === 'function') {
  scrollObservable = this.scrollObservable(image, offset) // and maybe more
} else {
  scrollObservable = this.scrollObservable.startWith('');
}

Nous ne pouvons pas réécrire le composant ci-dessus pour :

@Component({
  selector: 'intersection-observer',
  template: `<img [defaultImage]="defaultImage" [lazyLoad]="image"
 [scrollObservable]="startLazyload" offest="50">`,
})
export class IntersectionObserverComponent {
  defaultImage = 'https://www.placecage.com/1000/1000';
  image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';

  startLazyload(image, offset) {
    Observable.create(observer => {
      const intersectionObserver = new IntersectionObserver(entries => {
        entries.forEach(entry => {
          if (entry.intersectionRatio > 0) {
            observer.next();
          }
        });
      }, {
        rootMargin: offset ? `${offset}px` : undefined,
        threshold: 0.01
      });
      intersectionObserver.observe(image);
      return () => observer.unobserve(image);
    });
  }
}

Mieux mais toujours un peu bruyant, surtout lorsque l'utilisateur veut utiliser IntersectionObserver sur toutes les images.

Un moyen de résoudre cela pourrait être de passer un Observable par défaut dans NgModule :

import { intersectionObserverLazyLoad } from 'some-place';

@NgModule({
    declarations: [ AppComponent ],
    imports: [ BrowserModule, lazyLoadImage({
      observable: intersectionObserverLazyLoad
    })],
    bootstrap: [ AppComponent ]
})
export class MyAppModule {}

Nous ne pouvons pas réécrire le composant ci-dessus pour :

@Component({
  selector: 'intersection-observer',
  template: `<img [defaultImage]="defaultImage" [lazyLoad]="image" offest="50">`,
})
export class IntersectionObserverComponent {
  defaultImage = 'https://www.placecage.com/1000/1000';
  image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
}

La possibilité de passer des fonctions par défaut dans NgModule pourrait également ouvrir des portes pour créer des fonctions personnalisées pour isVisible et loadImage mais c'est une histoire plus tardive.

Résoudrait : #287, #195, #286, #285, #275, #259 et plus. La plupart des problèmes sont résolus par d'autres moyens, mais ce serait bien si nous pouvions donner à l'utilisateur plus de flexibilité lors de la création d'un observable.

Qu'en pensez-vous @sapierens , @rimlin ?

help wanted

Commentaire le plus utile

@tjoskar si je comprends bien, vous souhaitez améliorer scrollObservable en fournissant une fonction en option pour scrollObservable , qui renverra Observable, qui est responsable d'émettre un événement de chargement d'image ? Si c'est le cas, je pense que c'est une idée vraiment cool !
Mais je pense qu'il est préférable d'utiliser un objet au lieu d'énumérer des arguments :

...
} else if (typeof this.scrollObservable === 'function') {
  scrollObservable = this.scrollObservable({
    image, 
    offset
  });
} else {
...

Tous les 4 commentaires

@tjoskar si je comprends bien, vous souhaitez améliorer scrollObservable en fournissant une fonction en option pour scrollObservable , qui renverra Observable, qui est responsable d'émettre un événement de chargement d'image ? Si c'est le cas, je pense que c'est une idée vraiment cool !
Mais je pense qu'il est préférable d'utiliser un objet au lieu d'énumérer des arguments :

...
} else if (typeof this.scrollObservable === 'function') {
  scrollObservable = this.scrollObservable({
    image, 
    offset
  });
} else {
...

fournir une fonction en option pour scrollObservable, qui renverra Observable, qui est responsable d'émettre un événement de chargement d'image

Correct, je souhaiterais peut-être aussi renommer scrollObservable mais ce serait un changement radical.

je pense qu'il est préférable d'utiliser un objet au lieu d'énumérer des arguments

Accepter!

Je pense que c'est une bonne idée, surtout en passant un observateur par défaut.

je pense qu'il est préférable d'utiliser un objet au lieu d'énumérer des arguments

Je suis également d'accord avec cela.

Corrigé en #365 et en version 2.1.0

Cette page vous a été utile?
0 / 5 - 0 notes