Recobrir

    O serviço de sobreposição fornece uma maneira fácil e rápida de renderizar dinamicamente o conteúdo no primeiro plano de um aplicativo. O conteúdo a ser renderizado, também a maneira como ele renderiza (por exemplo, posicionamento, animações, comportamentos de rolagem e clique) são altamente configuráveis e capazes de corresponder a todos os cenários possíveis. O serviço de sobreposição é totalmente integrado na diretiva toggle.

    Angular Overlay Example

    Getting Started

    Primeiro precisamos importar o IgxOverlayService no componente e inject uma referência a ele no construtor do componente:

    
    import { Inject } from '@angular/core'
    import { IgxOverlayService } from `igniteui-angular`;
    
    ...
    
    export class MyOverlayComponent {
        constructor(
            @Inject(IgxOverlayService) private overlayService: IgxOverlayService
        ) {}
    }
    
    ...
    

    Displaying Content

    O serviço de sobreposição pode ser usado para exibir dinamicamente um HTMLNode ou até mesmo um componente Angular anexando-o ao DOM de sobreposição.

    Após uma referência ao serviço Overlay ser estabelecida, ela pode ser usada para mostrar/ocultar conteúdo dinamicamente. Por exemplo, podemos passar um Angular Component no método attach. Isso gerará um ID exclusivo, que podemos passar para o método show para exibir o componente. Ao exibir um Angular Component, um segundo parâmetro obrigatório ViewContainerRef deve ser passado no método attach.

    
    // my-overlay-component.component.ts
    import { MyDynamicComponent } from '../my-dynamic-component/my-dynamic-component.component';
    
    @Component({...})
    export class MyOverlayComponent {
        private _overlayId = ''; // The unique identifier assigned to the component by the Overlay service
    
        constructor(
            @Inject(IgxOverlayService) private overlayService: IgxOverlayService,
            private viewContainerRef: ViewContainerRef
        ) {}
    
        public showInOverlay() {
            if (!this._overlayId) {
                this._overlayId = this.overlayService.attach(MyDynamicComponent, this.viewContainerRef);
            }
            this.overlayService.show(this._overlayId);
        }
    }
    
    <!-- my-overlay-component.component.html -->
    <div class='content'>
    ...
        <button (click)="showInOverlay()">Show Overlay</button>
    </div>
    
    

    Se quisermos passar um ElementRef já existente da página para o IgxOverlayService, podemos fazer isso da seguinte maneira:

    <!-- my-overlay-component.component.html -->
    <div class='content'>
        <button (click)="showInOverlay()">Show Overlay</button>
    </div>
    <div>
        <img #exampleImage width='200px' src='../assets/example.png' title='Click Me!'>
    </div>
    
    // my-overlay-component.component.ts
    import { Inject, ViewChild } from '@angular/core'
    
    @Component({...})
    export class MyOverlayComponent {
        private _overlayId = ''; // The unique identifier assigned to the component by the Overlay service
    
        @ViewChild('exampleImage', {read: ElementRef})
        private exampleImage: ElementRef;
        public showInOverlay() {
            if (!this._overlayId) {
                this._overlayId = this.overlayService.attach(this.exampleImage);
            }
            this.overlayService.show(this._overlayId);
        }
    }
    

    O método attach() do Overlay Service tem duas sobrecargas:

    • attach(element, settings?)
    • attach(component, viewContainerRef, settings?)

    O primeiro parâmetro em ambas as sobrecargas é obrigatório e representa o conteúdo que será mostrado na sobreposição. Há alguns cenários diferentes de como o conteúdo pode ser passado:

    • Uma definição de componente - Ao passar um componente como o primeiro argumento, o serviço de sobreposição cria uma nova instância desse componente e anexa dinamicamente seu ElementRef ao DOM overlay. Esse método também aceita um segundo parâmetro obrigatório ViewContainerRef que é uma referência ao contêiner onde a visualização do host do componente criado será inserida.
    • Um ElementRef para um elemento DOM existente (ilustrado no exemplo acima) - Qualquer visualização que já esteja renderizada na página pode ser passada pelo serviço de sobreposição e renderizada no DOM de sobreposição.

    Em ambos os casos, o método attach() irá:

    • Obter a referência para a visualização passada do Angular
    • Desanexe a visualização do DOM e deixe uma âncora em seu lugar
    • Reanexe a visualização à sobreposição usando as OverlaySettings fornecidas ou retornando às sobreposições padrão

    Chamar show(id) reproduzirá a animação de abertura, se houver, e mostrará o conteúdo anexado. Chamar hide(id) reproduzirá a animação de fechamento, se houver, e ocultará o conteúdo anexado.

    Finalmente, chamar o método detach(id) irá re-anexar a visualização de volta ao seu local original no DOM. Se um componente foi fornecido ao método attach() chamar detach(id) irá destruir a instância criada.

    Attaching Components

    Na demonstração abaixo, podemos passar o componente IgxCard pelo método attach() do Overlay Service para gerar um ID. Então, chamamos o método show() com o ID fornecido para anexar dinamicamente o cartão ao DOM em um contêiner modal.

    Overlay Settings

    O método attach() também aceita um objeto do tipo OverlaySettings, que configura a maneira como o conteúdo é exibido. Se nenhum objeto desse tipo for fornecido, o Overlay Service usará suas configurações padrão para renderizar o conteúdo passado.

    Por exemplo, se quisermos que o conteúdo seja posicionado em relação a um elemento, podemos passar um target e positioningStrategy diferentes para o método attach(), por exemplo, ConnectedPositioningStrategy. Para configurar como o componente é exibido, precisamos criar um objeto OverlaySettings primeiro:

    // my-overlay-component.component.ts
    // import the ConnectedPositioningStategy class
    import { ConnectedPositioningStrategy } from 'igniteui-angular';
    // import { ConnectedPositioningStrategy } from '@infragistics/igniteui-angular'; for licensed package
    ...
    export class MyOverlayComponent {
    
        @ViewChild(`myAnchorButton`)
        private myAnchorButton: ElementRef;
        private _overlayId = ''; // The unique identifier assigned to the component by the Overlay service
    
        public showInOverlay() {
            if (!this._overlayId) {
                this._overlayId = this.overlayService.attach(MyDynamicComponent, this.viewContainerRef, {
                    target: this.myAnchorButton.nativeElement,
                    positionStrategy: new ConnectedPositioningStrategy()
                });
            }
            this.overlayService.show(this._overlayId);
        }
    }
    
    <!-- my-overlay-component.component.html -->
    <div class='content'>
    ...
    <button #myAnchorButton (click)="showInOverlay()">Show Overlay</button>
    </div>
    

    Clicar no botão agora mostrará MyDynamicComponent posicionado em relação ao botão.

    Preset Overlay Settings

    Os métodos IgxOverlayService.createAbsolutePositionSettings() e IgxOverlayService.createRelativePositionSettings() fornecem uma maneira fácil de criar um OverlaySettings com base em conjuntos de configurações predefinidos.

    O método IgxOverlayService.createAbsolutePositionSettings() cria OverlaySettings não modais com GlobalPositionStrategy ou ContainerPositionStrategy caso o parâmetro outlet seja fornecido. A enumeração AbsolutePosition define as posições possíveis para escolher: Center, Top ou Bottom. A posição padrão é Center.

    const globalOverlaySettings = IgxOverlayService.createAbsoluteOverlaySettings(AbsolutePosition.Top);
    

    O método IgxOverlayService.createRelativePositionSettings() cria OverlaySettings com AutoPositionStrategy, ConnectedPositioningStrategy ou ElasticPositionStrategy. Aceita target, position e strategy. O target é o ponto de anexação ou elemento para o componente mostrar. A position é uma enumeração RelativePosition com as seguintes opções: Above, Below, Before, After e Default. A opção Default posiciona o elemento abaixo do target, alinhado à esquerda. A estratégia de posição pode ser definida por meio da enumeração RelativePositionStrategy, cujo valor padrão é Auto.

    const targetElement = this.myAnchorButton.nativeElement;
    const connectedOverlaySettings = IgxOverlayService.createRelativeOverlaySettings(
            targetElement,
            RelativePosition.Above,
            RelativePositionStrategy.Connected);
    

    Demo

    Hiding the Overlay

    O hide(id) oculta o conteúdo da sobreposição. Todos os elementos renderizados pelo serviço de sobreposição têm um ID exclusivo, atribuído a eles pelo serviço. O método attach() retorna o identificador do conteúdo renderizado. Para ocultar o conteúdo, esse ID precisa ser passado para o método hide(id) da sobreposição. Para ocultar todas as sobreposições, o método hideAll() pode ser chamado.

    Quando o conteúdo renderizado não for mais necessário, o método detach(id) deve ser chamado. Este método remove o conteúdo da sobreposição e, se aplicável, o reconecta ao seu local original no DOM. O método detach(id) também aceita como parâmetro obrigatório o ID gerado pelo método attach(). Para remover todas as sobreposições, o método detachAll() pode ser chamado.

    Podemos modificar o método de sobreposição definido anteriormente para não apenas mostrar, mas também ocultar o elemento de sobreposição

    // my-overlay-component.component.ts
    // add an import for the definion of ConnectedPositioningStategy class
    import { ConnectedPositioningStrategy } from 'igniteui-angular';
    // import { ConnectedPositioningStrategy } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({...})
    export class MyOverlayComponent implements OnDestroy {
        private _overlayId = ''; // The unique identifier assigned to the component by the Overlay service
        private _overlayShown = false; // Is the component rendered in the Overlay?
    
        @ViewChild(`myAnchorButton`)
        private myAnchorButton: ElementRef;
    
        public toggleOverlay() {
            if (!this._overlayShown) { // If the element is not visible, show it
                //  generate ID
                if (!this._overlayId) {
                    this._overlayId = this.overlayService.attach(MyDynamicComponent, this.viewContainerRef, {
                        target: this.myAnchorButton.nativeElement,
                        positionStrategy: new ConnectedPositioningStrategy({
                            closeOnOutsideClick: false, // overlay will not close on outside clicks
                            modal: false // overlay content will not be rendered in a modal dialog
                        }) // The attach method returns an ID that can be used to reference the shown content
                    });
                }
    
                this.overlayService.show(this._overlayId);
            } else {
                this.overlayService.hide(this._overlayId); // If element if visible, hide it
            }
            this._overlayShown = !this._overlayShown;
        }
    
        // finally detach overlay content
        public ngOnDestroy(): void {
            if (this._overlayId) {
                this.overlayService.detach(this._overlayId);
                delete this._overlayId;
            }
        }
    }
    
    <!-- my-overlay-component.component.html -->
    <div class='content'>
    ...
        <button #myAnchorButton (click)="toggleOverlay()">Toggle Overlay</button>
    </div>
    

    Attaching Settings

    Usando o parâmetro overlaySettings do método attach(), podemos alterar como o conteúdo é exibido - por exemplo, onde o conteúdo é posicionado, como a rolagem deve se comportar e se o contêiner é modal ou não

    Se nenhuma overlaySettings for configurada, o elemento alternado obterá as configurações de exibição padrão:

    defaultOverlaySettings = {
        positionStrategy: new GlobalPositionStrategy(),
        scrollStrategy: new NoOpScrollStrategy(),
        modal: true,
        closeOnOutsideClick: true,
        closeOnEscape: false
    };
    

    Integration with igxToggle

    A IgxToggleDirective é totalmente integrada com a IgxOverlayService. Como tal, o método toggle() da Toggle Directive permite que configurações de sobreposição personalizadas sejam passadas ao alternar o conteúdo.

    Um exemplo de como passar configurações para o método toggle é mostrado abaixo:

    <!-- In example.component.html -->
    <div>
        <button igxToggle (click)="callToggle()">Click me!</button>
        <div [style.visibility]="collapsed ? 'hidden ' : 'visible'">
            This content is toggle-able!
        </div>
    </div>
    
    // example.component.ts
    @Component({
        selector: `example-component`,
        template: `example.component.html`
    })
    export class ExampleComponent {
        @ViewChild(IgxToggleDirective)
        private toggleDirective: IgxToggleDirective;
    
        public get collapsed(): boolean {
            return this.toggleDirective.collapsed;
        }
    
        public callToggle(): void {
            const overlaySettings: OverlaySettings = {
                positionStrategy: new AutoPositionStrategy(),
                scrollStrategy: new BlockScrollStrategy(),
                modal: true,
                closeOnOutsideClick: false
            }
            this.toggleDirective.toggle(overlaySettings)
        }
    }
    

    Assumptions and Limitations

    Se você mostrar a sobreposição em um outlet, e se o outlet for filho de um elemento com transform, perspective ou filter definido no CSS, você não poderá mostrar a sobreposição modal. O motivo para isso é que se uma das propriedades CSS mencionadas acima for definida, o navegador cria um novo bloco de contenção e a sobreposição é limitada a esse bloco de contenção, conforme descrito aqui.

    API References

    Additional Resources