Ng-lazyload-image: Funktionsanfrage: Erhalten Sie Zugriff auf das Bild in der beobachtbaren Erstellung

Erstellt am 3. Feb. 2018  ·  4Kommentare  ·  Quelle: tjoskar/ng-lazyload-image

Motivation und Umsetzung

Im Moment ist es möglich, ein Observable zu passieren, was eine großartige Möglichkeit ist, die Bibliothek zu erweitern. Es ist jedoch etwas eingeschränkt, da die Benutzer nicht auf einfache Weise auf das Bild zugreifen können.

Eines der häufigsten Probleme ist, wenn der Benutzer das Fenster nicht zum Scrollen verwendet oder eine 3-teilige Bibliothek verwendet, die zusätzliche Scroll-Layer hinzufügt (z. B. ionisch, ng Materialdesign usw.), und es kann manchmal schwer zu finden sein heraus, welches Element tatsächlich scrollt. Eine Möglichkeit, dies zu lösen, könnte darin bestehen, ein Intersection Observer (was auch eine Leistungssteigerung bewirken kann). Z.B.

@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);
  }
}

Dies ist jedoch recht umständlich.

Was wir tun können, ist eine Funktion als scrollObservable zu akzeptieren, etwa wie:

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('');
}

Wir können die obige Komponente nicht umschreiben in:

@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);
    });
  }
}

Besser, aber immer noch ein bisschen laut, besonders wenn der Benutzer IntersectionObserver für alle Bilder verwenden möchte.

Eine Möglichkeit, dies zu lösen, könnte darin bestehen, ein Standard-Observable in NgModule :

import { intersectionObserverLazyLoad } from 'some-place';

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

Wir können die obige Komponente nicht umschreiben in:

@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';
}

Die Möglichkeit, Standardfunktionen in NgModule zu übergeben, könnte auch Türen öffnen, um benutzerdefinierte Funktionen für isVisible und loadImage zu erstellen, aber das ist eine spätere Geschichte.

Würde lösen: #287, #195, #286, #285, #275, #259 und mehr. Die meisten Probleme werden auf andere Weise gelöst, aber es wäre schön, wenn wir dem Benutzer mehr Flexibilität beim Erstellen eines Observables geben könnten.

Was denkst du @sapierens , @rimlin?

help wanted

Hilfreichster Kommentar

@tjoskar Wie ich verstehe, möchten Sie scrollObservable verbessern, indem Sie eine Funktion als Option für scrollObservable bereitstellen, die Observable zurückgibt, das für das
Aber ich denke, es ist besser, ein Objekt zu verwenden, anstatt Argumente aufzuzählen:

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

Alle 4 Kommentare

@tjoskar Wie ich verstehe, möchten Sie scrollObservable verbessern, indem Sie eine Funktion als Option für scrollObservable bereitstellen, die Observable zurückgibt, das für das
Aber ich denke, es ist besser, ein Objekt zu verwenden, anstatt Argumente aufzuzählen:

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

stellen Sie eine Funktion als Option für scrollObservable bereit, die Observable zurückgibt, das dafür verantwortlich ist, ein Bildladeereignis auszugeben

Richtig, ich möchte vielleicht auch scrollObservable umbenennen, aber das wäre eine bahnbrechende Änderung.

Ich denke, es ist besser, ein Objekt zu verwenden, anstatt Argumente aufzuzählen

Zustimmen!

Ich denke, das ist eine nette Idee, besonders wenn man einen Standardbeobachter passiert.

Ich denke, es ist besser, ein Objekt zu verwenden, anstatt Argumente aufzuzählen

Dem stimme ich auch zu.

Behoben in #365 und in Version 2.1.0

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen