Angularのポータルパターン:TaigaUIにルートコンポーネントが必要な理由

私の同僚のRomanは最近、Angular TaigaUI用の新しいコンポーネントライブラリのリリースを発表しまし入門手順には、アプリケーションをでラップする必要があると書かれていますtui-root



それが何をするのか、ポータルを使用する方法と理由、そしてポータルが一般的に何であるかを理解しましょう。





ポータルとは何ですか?

コンポーネントを想像してみてくださいselect



選択可能なオプションのあるドロップダウンがあります。コンポーネント自体と同じDOM内の場所に保存すると、いくつかの問題が発生する可能性があります。下流の要素が上に飛び出し、コンテナがコンテンツを切り取る可能性があります。





z-index



, Z . 100, 10000, 10001. , overflow: hidden



. ?





. z-index



. «». Root- Taiga UI . :





<tui-scroll-controls></tui-scroll-controls>
<tui-portal-host>
    <div class="content"><ng-content></ng-content></div>
    <tui-dialog-host></tui-dialog-host>
    <ng-content select="tuiOverDialogs"></ng-content>
    <tui-notifications-host></tui-notifications-host>
    <ng-content select="tuiOverNotifications"></ng-content>
</tui-portal-host>
<ng-content select="tuiOverPortals"></ng-content>
<tui-hints-host></tui-hints-host>
<ng-content select="tuiOverHints"></ng-content>
      
      



tui-dialog-host



, tui-portal-host



— . -. . Taiga UI . . :





@Injectable({
   providedIn: 'root',
})
export class TuiPortalService {
   private host: TuiPortalHostComponent;

   add<C>(componentFactory: ComponentFactory<C>, injector: Injector): ComponentRef<C> {
       return this.host.addComponentChild(componentFactory, injector);
   }

   remove<C>({hostView}: ComponentRef<C>) {
       hostView.destroy();
   }

   addTemplate<C>(templateRef: TemplateRef<C>, context?: C): EmbeddedViewRef<C> {
       return this.host.addTemplateChild(templateRef, context);
   }

   removeTemplate<C>(viewRef: EmbeddedViewRef<C>) {
       viewRef.destroy();
   }
}
      
      



. , , — . , , .





, - . , «», .





, . :





  1. . Material .





  2. , . .





  3. .





. , . , requestAnimationFrame



. — , . . , . , . , . .









— . Obscured. .





, . , .





:





<section
   *ngFor="let item of dialogs$ | async"
   polymorpheus-outlet
   tuiFocusTrap
   tuiOverscroll="all"
   class="dialog"
   role="dialog"
   aria-modal="true"
   [attr.aria-labelledby]="item.id"
   [content]="item.component"
   [context]="item"
   [@tuiParentAnimation]
></section>
<div class="overlay"></div>
      
      



, ngFor



, . , . , . , .





, . Taiga UI — . - iOS Android. . , .





Observable



. , — . . . , , DI- POLYMORPHEUS_CONTEXT



. content



observer



. complete



, , next



. , , . :





const DIALOG = new PolymorpheusComponent(MyDialogComponent);
const DEFAULT_OPTIONS: MyDialogOptions = {
   label: '',
   size: 's',
};

@Injectable({
   providedIn: 'root',
})
export class MyDialogService extends AbstractTuiDialogService<MyDialogOptions> {
   protected readonly component = DIALOG;
   protected readonly defaultOptions = DEFAULT_OPTIONS;
}
      
      



.





, Taiga UI, ng-polymorpheus . , , , .





tuiFocusTrap



. , DOM, , . - — :





@HostListener('window:focusin.silent', ['$event.target'])
onFocusIn(node: Node) {
   if (containsOrAfter(this.elementRef.nativeElement, node)) {
       return;
   }

   const focusable = getClosestKeyboardFocusable(
       this.elementRef.nativeElement,
       false,
       this.elementRef.nativeElement,
   );

   if (focusable) {
       focusable.focus();
   }
}
      
      



root-. root , tuiOverscroll



. CSS- overscroll-behavior. . , , . , , .





: tui-root?

, . , root-. tui-scroll-controls



. , . <ng-content select="tuiOverDialogs"></ng-content>



. Taiga UI. , .





root event manager plugin` DI. — . , TuiRootModule



BrowserModule



, . : — .





, root-. Taiga UI open-source, «» npm. StackBlitz-. , , !








All Articles