A web é um ambiente rico em recursos. Podemos navegar na realidade virtual com um gamepad, tocar um sintetizador com um teclado MIDI, comprar produtos com apenas um toque de nosso dedo. Todos esses recursos impressionantes são fornecidos por APIs nativas, que, como sua funcionalidade, são extremamente diversas.
Angular é uma plataforma excelente com algumas das melhores ferramentas no ambiente de front-end. E, claro, existe uma certa maneira de fazer isso "no jeito Angulyar". O que eu pessoalmente adoro nessa estrutura é a sensação de satisfação que você obtém quando tudo é feito da maneira certa: código limpo, arquitetura clara. Vamos dar uma olhada no que torna o código escrito corretamente em Angular.
O jeito Angular
Angular, , , , . , , , Angular « ». : . opensource- Web APIs for Angular. — , API Angular. @ng-web-apis/intersection-observer.
, :
- Angular , JavaScript- .
- Angular , .
- Angular Observable, API .
.
vs
, , IntersectionObserver
:
const callback = entries => { ... };
const options = {
root: document.querySelector('#scrollArea'),
rootMargin: '10px',
threshold: 1
};
const observer = new IntersectionObserver(callback, options);
observer.observe(document.querySelector('#target'));
API
, , . Angular :
<div
waIntersectionObserver
waIntersectionThreshold="1"
waIntersectionRootMargin="10px"
(waIntersectionObservee)="onIntersection($event)"
>
I'm being observed
</div>
Angular Payment Request API. , .
2 : , — . . . -, . observe
/unobserve
.
IntersectionObserver
Map
. , , :
@Directive({
selector: '[waIntersectionObserver]',
})
export class IntersectionObserverDirective extends IntersectionObserver
implements OnDestroy {
private readonly callbacks = new Map<Element, IntersectionObserverCallback>();
constructor(
@Optional() @Inject(INTERSECTION_ROOT) root: ElementRef<Element> | null,
@Attribute('waIntersectionRootMargin') rootMargin: string | null,
@Attribute('waIntersectionThreshold') threshold: string | null,
) {
super(
entries => {
this.callbacks.forEach((callback, element) => {
const filtered = entries.filter(({target}) => target === element);
return filtered.length && callback(filtered, this);
});
},
{
root: root && root.nativeElement,
rootMargin: rootMargin || ROOT_MARGIN_DEFAULT,
threshold: threshold
? threshold.split(',').map(parseFloat)
: THRESHOLD_DEFAULT,
},
);
}
observe(target: Element, callback: IntersectionObserverCallback = () => {}) {
super.observe(target);
this.callbacks.set(target, callback);
}
unobserve(target: Element) {
super.unobserve(target);
this.callbacks.delete(target);
}
ngOnDestroy() {
this.disconnect();
}
}
— .
Dependency Injection
DI Angular , . . , , . , , . :
@Directive({
selector: '[waIntersectionRoot]',
providers: [
{
provide: INTERSECTION_ROOT,
useExisting: ElementRef,
},
],
})
export class IntersectionRootDirective {}
:
<div waIntersectionRoot>
...
<div
waIntersectionObserver
waIntersectionThreshold="1"
waIntersectionRootMargin="10px"
(waIntersectionObservee)="onIntersection($event)"
>
I'm being observed
</div>
...
</div>
DI , , Web Audio API Angular.
— . . , - -, .
DI IntersectionObserver
RxJS Observable
, .
Observables
API , Angular RxJs . Observable
, , — . - IntersectionObserver
, Observable
. , :
@Injectable()
export class IntersectionObserveeService extends Observable<IntersectionObserverEntry[]> {
constructor(
@Inject(ElementRef) {nativeElement}: ElementRef<Element>,
@Inject(IntersectionObserverDirective)
observer: IntersectionObserverDirective,
) {
super(subscriber => {
observer.observe(nativeElement, entries => {
subscriber.next(entries);
});
return () => {
observer.unobserve(nativeElement);
};
});
}
}
Observable
, IntersectionObserver
. Angular, new
-.
Observable
- Geolocation API Resize Observer API, .
Output
. EventEmitter
, Observable
, , :
@Directive({
selector: '[waIntersectionObservee]',
outputs: ['waIntersectionObservee'],
providers: [IntersectionObserveeService],
})
export class IntersectionObserveeDirective {
constructor(
@Inject(IntersectionObserveeService)
readonly waIntersectionObservee: Observable<IntersectionObserverEntry[]>,
) {}
}
, RxJs-, map
, filter
, switchMap
, .
, IntersectionObserver
Observable
. DI . 1 .gzip Github npm.
, , . , . , , Internet Explorer.
, . , API Angular. - , Canvas MIDI-, — .
GDG DevParty Russia, API Angular. , :