es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Error al utilizar la superposición de Angular CDK que no se inicializa correctamente y no se posiciona correctamente.

Tengo un componente que quiero abrir cuando se hace clic en ciertos botones y cerrar cuando se cierra en cualquier parte fuera del componente. Decidí que podría usar cdkOverlay para esto, pero no estoy muy familiarizado con él y estoy teniendo dificultades para hacer que funcione correctamente.
Este es un diagrama simple de lo que estoy tratando de lograr:

Hay dos botones en el componente1 y componente2 que pueden abrir el overlay. El overlay siempre está al lado del componente1. La forma en que está estructurada la aplicación, estoy activando el componente del overlay a través de un servicio y lo he declarado en el componente1.
Cuando intento usar cdkOverlay, obtengo el siguiente error:

Uncaught TypeError: No se pueden leer las propiedades de indefinido (leyendo ‘ancho’)
en FlexibleConnectedPositionStrategy._getOriginRect

Y aquí hay un fragmento del código que tengo hasta ahora (en componente1):


… varios divs y componentes

… resto del componente de overlay

y el css:

.container {
height: 400px;
width: 150px;

position: absolute;
top: 0;
left: -161px;

}
:host {
position: absolute;
width: 100%;
display: flex;
flex-direction: column;
height: calc(100vh – #{$vertical-menu-heading-height});
margin: (-$sidebar-margin-vertical) (-$sidebar-margin-horizontal);
padding: ($sidebar-margin-vertical + 10px) $sidebar-margin-horizontal 0 $sidebar-margin-horizontal;
}

:host.collapsed-view {
position: initial;
margin: 0;
padding: 0;
}

Puedo mostrar el componente bien. Solo cuando intenté introducir el cdkoverlay para poder ocultarlo al hacer clic fuera, es cuando dejó de funcionar.

Espero (estoy bastante seguro) que sea algo simple que lo arreglará y que simplemente no conozco.
¡Agradecería cualquier sugerencia sobre cómo hacer que funcione y permitir que se posicione correctamente!

¡Gracias!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que el error que estás experimentando con cdkOverlay se debe a un problema con la estrategia de posición, específicamente con la propiedad width.

    Una solución potencial sería definir explícitamente la estrategia de posición en el código de tu componente, de la siguiente manera:

    import { Component, ElementRef, ViewChild, ViewContainerRef } from '@angular/core';
    import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
    import { ComponentPortal } from '@angular/cdk/portal';
    
    @Component({
      selector: 'app-componente1',
      template: `
        <ng-container>... varios divs y componentes</ng-container>
        <button (click)="openOverlay()">Abrir Overlay</button>
      `
    })
    export class Componente1 {
      private overlayRef: OverlayRef;
      @ViewChild('overlayContainer') overlayContainer: ElementRef;
    
      constructor(
        private overlay: Overlay,
        private viewContainerRef: ViewContainerRef
      ) {}
    
      openOverlay() {
        const config = new OverlayConfig({
          hasBackdrop: true,
          positionStrategy: this.overlay.position()
            .flexibleConnectedTo(this.overlayContainer.nativeElement)
            .withPositions([
              { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top' }
            ])
        });
        this.overlayRef = this.overlay.create(config);
        const portal = new ComponentPortal(ComponenteOverlay);
        this.overlayRef.attach(portal);
        this.overlayRef.backdropClick().subscribe(() => this.closeOverlay());
      }
    
      closeOverlay() {
        this.overlayRef.detach();
      }
    }
    

    Este código define un OverlayConfig que establece explícitamente la estrategia de posición como flexibleConnectedTo, lo que significa que adjuntará el overlay a elementRef, en este caso overlayContainer. withPositions define dónde debería posicionarse el overlay en relación con elementRef.

    Además, este código inicializa el componente del overlay con un ComponentPortal, que debe estar registrado en entryComponents en tu módulo.

    ¡Espero que esto ayude! Déjame saber si tienes alguna otra pregunta.

Comments are closed.