The web is a feature-rich environment. We can navigate virtual reality with a gamepad, play synthesizer with a MIDI keyboard, buy goods with just one touch of our finger. All of these impressive capabilities are provided by native APIs, which, like their functionality, are extremely diverse.
Angular is an excellent platform with some of the best tools in the front-end environment. And, of course, there is a certain way to do it "in Angulyar" way. What I personally love about this framework is the satisfaction that you get when everything is done right: neat code, clear architecture. Let's take a look at what makes the code properly written in Angular.
The Angular way
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. , :