Ng-lazyload-image: Solicitação de recurso: obtenha acesso à imagem na criação observável

Criado em 3 fev. 2018  ·  4Comentários  ·  Fonte: tjoskar/ng-lazyload-image

Motivação e implementação

Agora é possível passar um observável que é uma ótima maneira de estender a biblioteca. No entanto, é um pouco limitado, pois os usos não conseguem acessar a imagem de forma simples.

Um dos problemas mais comuns é quando o usuário não usa a janela para rolar ou usa uma biblioteca de 3 partes que adiciona camadas de rolagem extras (por exemplo, iônico, design de material ng, etc), e às vezes pode ser difícil de encontrar qual elemento realmente rola. Uma maneira de resolver isso poderia ser usar Intersection Observer (que também pode aumentar o desempenho). Por exemplo.

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

No entanto, isso é bastante complicado.

O que podemos fazer é aceitar uma função como scrollObservable , algo como:

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

Não podemos reescrever o componente acima para:

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

Melhor, mas ainda um pouco barulhento, especialmente quando o usuário deseja usar IntersectionObserver em todas as imagens.

Uma maneira de resolver isso poderia ser passar um Observável padrão em NgModule :

import { intersectionObserverLazyLoad } from 'some-place';

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

Não podemos reescrever o componente acima para:

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

A capacidade de passar funções padrão no NgModule também pode abrir portas para criar funções personalizadas para isVisible e loadImage mas isso é uma história posterior.

Resolveria: # 287, # 195, # 286, # 285, # 275, # 259 e mais. A maioria dos problemas é resolvida de outras maneiras, mas seria bom se pudéssemos dar ao usuário mais flexibilidade ao criar um observável.

O que você acha @sapierens , @rimlin?

help wanted

Comentários muito úteis

@tjoskar pelo que entendi, você deseja aprimorar scrollObservable fornecendo função como opção para scrollObservable , que retornará Observable, que é responsável por emitir o evento de carregamento de imagem? Se for, eu acho que é uma ideia muito legal!
Mas acho melhor usar objeto em vez de enumerar argumentos:

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

Todos 4 comentários

@tjoskar pelo que entendi, você deseja aprimorar scrollObservable fornecendo função como opção para scrollObservable , que retornará Observable, que é responsável por emitir o evento de carregamento de imagem? Se for, eu acho que é uma ideia muito legal!
Mas acho melhor usar objeto em vez de enumerar argumentos:

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

fornecer função como opção para scrollObservable, que retornará Observable, que é responsável por emitir o evento de carregamento de imagem

Correto, também posso renomear scrollObservable mas isso seria uma alteração importante.

eu acho que é melhor usar objeto em vez de enumerar argumentos

Concordar!

Acho que é uma boa ideia, especialmente passar por um observador padrão.

eu acho que é melhor usar objeto em vez de enumerar argumentos

Eu também concordo com isso.

Corrigido no # 365 e na versão 2.1.0

Esta página foi útil?
0 / 5 - 0 avaliações