Cubrir

    El servicio de superposición proporciona una manera fácil y rápida de representar dinámicamente contenido en primer plano de una aplicación. El contenido que se va a representar, así como la forma en que se presenta (por ejemplo, ubicación, animaciones, comportamientos de desplazamiento y clic) son altamente configurables y pueden adaptarse a todos los escenarios posibles. El servicio de superposición está completamente integrado en la directiva de alternancia.

    Angular Overlay Example

    Getting Started

    Primero necesitamos importar IgxOverlayService en el componente e inject una referencia en el constructor del componente:

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

    Displaying Content

    El servicio de superposición se puede utilizar para mostrar dinámicamente un HTMLNode o incluso un componente Angular adjuntándolo al DOM superpuesto.

    Una vez establecida una referencia al servicio Overlay, se puede utilizar para mostrar/ocultar contenido dinámicamente. Por ejemplo, podemos pasar un componente Angular en el método attach. Esto generará una identificación única, que podemos pasar al método show para mostrar el componente. Al mostrar un componente Angular, se debe pasar un segundo parámetro obligatorio ViewContainerRef en el 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>
    
    

    Si queremos pasar un ElementRef ya existente de la página al IgxOverlayService, podemos hacerlo de la siguiente manera:

    <!-- 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);
        }
    }
    

    El método attach() del servicio Overlay tiene dos sobrecargas:

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

    El primer parámetro en ambas sobrecargas es obligatorio y representa el contenido que se mostrará en la superposición. Hay un par de escenarios diferentes en los que se puede transmitir el contenido:

    • Una definición de componente: al pasar un componente como primer argumento, el servicio de superposición crea una nueva instancia de ese componente y adjunta dinámicamente su ElementRef al DOM overlay. Este método también acepta un segundo parámetro obligatorio ViewContainerRef que es una referencia al contenedor donde se insertará la vista de host del componente creado.
    • Un ElementRef para un elemento DOM existente (ilustrado en el ejemplo anterior): cualquier vista que ya esté representada en la página puede pasar a través del servicio de superposición y representarse en el DOM superpuesto.

    En ambos casos, el método attach():

    • Obtenga la referencia a la vista pasada desde Angular
    • Separe la vista del DOM y deje un ancla en su lugar
    • Vuelva a adjuntar la vista a la superposición usando los OverlaySettings proporcionados o recurriendo a los de superposición predeterminados

    Al llamar a show(id) se reproducirá la animación abierta, si la hay, y se mostrará el contenido adjunto. Llamar a hide(id) reproducirá una animación de cierre, si la hay, y ocultará el contenido adjunto.

    Finalmente, llamar al método detach(id) volverá a adjuntar la vista a su ubicación original en el DOM. Si se proporcionó un componente al método attach() llamar detach(id) destruirá la instancia creada.

    Attaching Components

    En la siguiente demostración, podemos pasar el componente IgxCard a través del método attach() del servicio Overlay para generar una identificación. Luego llamamos al método show() con el ID proporcionado para adjuntar dinámicamente la tarjeta al DOM en un contenedor modal.

    Overlay Settings

    El método attach() también acepta un objeto del tipo OverlaySettings, que configura la forma en que se muestra el contenido. Si no se proporciona dicho objeto, el Servicio de superposición utilizará su configuración predeterminada para representar el contenido pasado.

    Por ejemplo, si queremos que el contenido se posicione en relación con un elemento, podemos pasar un target y positioningStrategy diferentes al método attach(), por ejemplo, ConnectedPositioningStrategy. Para configurar cómo se muestra el componente, primero debemos crear un objeto OverlaySettings:

    // 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>
    

    Al hacer clic en el botón ahora se mostrará MyDynamicComponent colocado en relación con el botón.

    Preset Overlay Settings

    Los métodos IgxOverlayService.createAbsolutePositionSettings() e IgxOverlayService.createRelativePositionSettings() proporcionan una manera fácil de crear OverlaySettings basado en conjuntos de configuraciones predefinidos.

    El método IgxOverlayService.createAbsolutePositionSettings() crea OverlaySettings no modales con GlobalPositionStrategy o ContainerPositionStrategy en caso de que se proporcione el parámetro outlet. La enumeración AbsolutePosition define las posibles posiciones para elegir: Center, Top o Bottom. La posición predeterminada es Center.

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

    El método IgxOverlayService.createRelativePositionSettings() crea OverlaySettings con AutoPositionStrategy, ConnectedPositioningStrategy o ElasticPositionStrategy. Acepta objetivo, posición y estrategia. El target es el punto o elemento de unión que se mostrará en el componente. La position es una enumeración RelativePosition con las siguientes opciones: Above, Below, Before, After y Default. La opción Default coloca el elemento debajo del objetivo, alineado a la izquierda. La estrategia de posición se puede establecer mediante la enumeración RelativePositionStrategy, cuyo valor predeterminado es Auto.

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

    Demo

    Hiding the Overlay

    hide(id) oculta el contenido superpuesto. Todos los elementos representados por el servicio de superposición tienen una identificación única que les asigna el servicio. El método attach() devuelve el identificador del contenido renderizado. Para ocultar el contenido, esta ID debe pasarse al método hide(id) de la superposición. Para ocultar todas las superposiciones, se puede llamar al método hideAll().

    Cuando el contenido renderizado ya no es necesario, se debe llamar al método detach(id). Este método elimina el contenido de la superposición y, si corresponde, lo vuelve a adjuntar a su ubicación original en el DOM. El método detach(id) también acepta como parámetro obligatorio el ID generado por el método attach(). Para eliminar todas las superposiciones, se puede llamar al método detachAll().

    Podemos modificar el método de superposición previamente definido para no solo mostrar sino también ocultar el elemento de superposición.

    // 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 el parámetro overlaySettings del método attach(), podemos cambiar cómo se muestra el contenido, por ejemplo, dónde se coloca el contenido, cómo debe comportarse el desplazamiento y si el contenedor es modal o no.

    Si no se configura ninguna overlaySettings, el elemento alternado obtiene la configuración de visualización predeterminada:

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

    Integration with igxToggle

    IgxToggleDirective está completamente integrado con IgxOverlayService. Como tal, el método toggle() de la directiva Toggle permite pasar configuraciones de superposición personalizadas al alternar el contenido.

    A continuación se muestra un ejemplo de cómo pasar ajustes de configuración al método de alternancia:

    <!-- 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

    Si muestra la superposición en una salida, y si la salida es hija de un elemento con transformación, perspectiva o filtro configurado en el CSS, no podrá mostrar la superposición modal. La razón de esto es que si se establece una de las propiedades CSS mencionadas anteriormente, el navegador crea un nuevo bloque contenedor y la superposición se limita a este bloque contenedor, como se describe aquí.

    API References

    Additional Resources