Ng-lazyload-image: Запрос функции: получить доступ к изображению в наблюдаемом создании

Созданный на 3 февр. 2018  ·  4Комментарии  ·  Источник: tjoskar/ng-lazyload-image

Мотивация и реализация

Прямо сейчас можно передать наблюдаемое, что является отличным способом расширить библиотеку. Однако он немного ограничен, поскольку пользователи не могут получить доступ к изображению простым способом.

Одна из наиболее распространенных проблем - это когда пользователь не использует окно для прокрутки или использует библиотеку из 3 частей, которая добавляет дополнительные слои прокрутки (например, ionic, ng material design и т. Д.), И иногда бывает трудно найти какой элемент на самом деле прокручивается. Один из способов решить эту проблему - использовать Intersection Observer (что также может повысить производительность). Например.

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

Однако это довольно громоздко.

Что мы можем сделать, так это принять функцию как scrollObservable , что-то вроде:

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

Мы не можем переписать приведенный выше компонент на:

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

Лучше, но все же немного шумно, особенно когда пользователь хочет использовать IntersectionObserver для всех изображений.

Способ решить эту проблему может заключаться в передаче наблюдаемого по умолчанию в NgModule :

import { intersectionObserverLazyLoad } from 'some-place';

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

Мы не можем переписать приведенный выше компонент так:

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

Возможность передавать функции по умолчанию в NgModule также может открыть двери для создания пользовательских функций для isVisible и loadImage но это позже.

Решил бы: # 287, # 195, # 286, # 285, # 275, # 259 и другие. Большинство проблем решаются другими способами, но было бы неплохо, если бы мы могли дать пользователю больше гибкости при создании наблюдаемого.

Как вы думаете, @sapierens , @rimlin?

help wanted

Самый полезный комментарий

@tjoskar, насколько я понимаю, вы хотите улучшить scrollObservable , предоставив функцию в качестве опции для scrollObservable , которая вернет Observable, который отвечает за создание события загрузки изображения? Если это так, я думаю, это действительно крутая идея!
Но я думаю, что лучше использовать объект вместо перечисления аргументов:

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

Все 4 Комментарий

@tjoskar, насколько я понимаю, вы хотите улучшить scrollObservable , предоставив функцию в качестве опции для scrollObservable , которая вернет Observable, который отвечает за создание события загрузки изображения? Если это так, я думаю, это действительно крутая идея!
Но я думаю, что лучше использовать объект вместо перечисления аргументов:

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

предоставить функцию в качестве опции для scrollObservable, которая вернет Observable, который отвечает за генерирование события загрузки изображения

Правильно, я могу также захотеть переименовать scrollObservable но это было бы критическим изменением.

я думаю, что лучше использовать объект вместо перечисления аргументов

Дать согласие!

Я думаю, что это хорошая идея, особенно передача наблюдателя по умолчанию.

я думаю, что лучше использовать объект вместо перечисления аргументов

Я тоже согласен с этим.

Исправлено в # 365 и в версии 2.1.0

Была ли эта страница полезной?
0 / 5 - 0 рейтинги