私の同僚の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();
}
}
. , , — . , , .
, - . , «», .
, . :
. Material .
, . .
.
. , . , 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-. , , !