Bagaimana menulis perpustakaan yang bagus untuk Angular

Web adalah lingkungan yang kaya fitur. Kita bisa menavigasi virtual reality dengan gamepad, memainkan synthesizer dengan keyboard MIDI, membeli barang hanya dengan satu sentuhan jari kita. Semua kemampuan mengesankan ini disediakan oleh API asli, yang, seperti fungsinya, sangat beragam.



Angular adalah platform luar biasa dengan beberapa alat terbaik di lingkungan front-end. Dan, tentu saja, ada cara tertentu untuk melakukannya "Angularly". Apa yang secara pribadi saya sukai dari framework ini adalah perasaan puas yang Anda dapatkan ketika semuanya dilakukan dengan benar: kode yang rapi, arsitektur yang jelas. Mari kita lihat apa yang membuat kode ditulis dengan benar dalam Angular.





Cara Angular



Angular, , , , . , , , Angular Β« Β». : . opensource- Web APIs for Angular. β€” , API Angular. @ng-web-apis/intersection-observer.



, :



  1. Angular , JavaScript- .
  2. Angular , .
  3. 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. , :






All Articles