Tengo componente principal y componente secundario. Componente hijo creado como componente modal. Así que he incluido el selector de componentes secundarios dentro del componente principal y he establecido que la encapsulación de la vista sea nula, por lo que tomará el componente principal css y todo, y también funciona, pero el componente primario tiene #paper id aplicando alguna biblioteca de terceros (rappidjs) libary css (para Diagramación SVG). Igual que el componente hijo tiene #dataMapper id. pero aquí el css de terceros no está tomando porque el componente hijo está establecido en 'encapsulation: ViewEncapsulation.None'
. Si voy a eliminar encapsulation: ViewEncapsulation.None
, está funcionando pero modal no está funcionando. todos los modales se cargan en lugar de onclick. Cómo resolver este problema, por favor avísame a alguien.
Codificación:
Componente principal TS
@Component({
selector: 'app-data-model',
templateUrl: './data-model.component.html',
styleUrls: ['./data-model.component.css']
})
export class DataModelComponent implements OnInit{
// Modal
openModal(id: string) {
this.modalApp = true;
this.modalService.open(id);
}
closeModal(id: string) {
this.modalService.close(id);
}
HTML de componente principal
<div id="toolbar">
<div class="tool-bar-section">
<button class="btn" (click)="openModal('custom-modal-1');"><i class="fa fa-file-excel-o" style="font-size: 24px"></i></button>
</div>
</div>
<div id="paper"> </div> ( this dom taking thirdparty css)
<app-modal id="custom-modal-1">
<h1 class="head-bar">Data Model - Import Excel <a href="#" class="close-icon" (click)="closeModal('custom-modal-1');"><i class="fa fa-times-circle-o" aria-hidden="true"></i></a></h1>
<div class="modal-content-section">
<ul>
<li><a href="#" (click)="closeModal('custom-modal-1');openModal('custom-modal-2');">Create New Schema</a></li>
<li><a href="#" (click)="closeModal('custom-modal-1');openModal('custom-modal-3');">Import Data to existing schema</a></li>
</ul>
</div>
</app-modal>
<app-modal id="custom-modal-2">
<h1 class="head-bar">Data Model - Import Excel <a href="#" class="close-icon" (click)="closeModal('custom-modal-2');"><i class="fa fa-times-circle-o" aria-hidden="true"></i></a></h1>
<div class="modal-content-section">
<div id="dataMapper"></div> ( this dom is not taking thirdparty css)
<p><a href="#" (click)="closeModal('custom-modal-2');openModal('custom-modal-4');">Data Mapping</a></p>
</div>
</app-modal>
HTML de componente hijo
<div class="app-modal">
<div class="app-modal-body">
<ng-content></ng-content>
</div>
</div>
<div class="app-modal-background"></div>
Componente secundario Ts
@Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css'],
encapsulation: ViewEncapsulation.None
})
export class ModalComponent implements OnInit, OnDestroy {
@Input() id: string;
private element: any;
constructor(private modalService: ModalService, private el: ElementRef) {
this.element = el.nativeElement;
}
ngOnInit(): void {
// ensure id attribute exists
if (!this.id) {
console.error('modal must have an id');
return;
}
// move element to bottom of page (just before </body>) so it can be displayed above everything else
document.body.appendChild(this.element);
// close modal on background click
this.element.addEventListener('click', el => {
if (el.target.className === 'app-modal') {
this.close();
}
});
// add self (this modal instance) to the modal service so it's accessible from controllers
this.modalService.add(this);
}
// remove self from modal service when component is destroyed
ngOnDestroy(): void {
this.modalService.remove(this.id);
this.element.remove();
}
// open modal
open(): void {
this.element.style.display = 'block';
document.body.classList.add('app-modal-open');
}
// close modal
close(): void {
this.element.style.display = 'none';
document.body.classList.remove('app-modal-open');
}
}
Código de servicio modal
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ModalService {
private modals: any[] = [];
add(modal: any) {
// add modal to array of active modals
this.modals.push(modal);
}
remove(id: string) {
// remove modal from array of active modals
this.modals = this.modals.filter(x => x.id !== id);
}
open(id: string) {
// open modal specified by id
const modal = this.modals.find(x => x.id === id);
modal.open();
}
close(id: string) {
// close modal specified by id
const modal = this.modals.find(x => x.id === id);
modal.close();
}
}
Avíseme si se requieren más detalles.
fuente
Respuestas:
Por tu modal. El modal se crea en la parte superior de su aplicación (fuera de la etiqueta del cuerpo si busca el contenedor modal al inspeccionarlo).
Es el modo modal porque la estructura dom no está sincronizada con la estructura del componente ng
Entonces, ¿por qué el modal funciona con ng
Encapsulation
? Porque su servicio modal puede manejarlo.Pero el archivo CSS de terceros no es parte de su configuración de compilación angular (es decir, solo sass, scss funciona). Por lo tanto, ignora cualquiera,
.css
incluso si lo importa correctamente.Para resolverlo, puede aplicar el .css a nivel mundial. O si tiene miedo de que eso pueda sobrescribir otros estilos globales, puede cambiar el nombre del archivo css a '_somefile.scss' (preste atención al guión '_', es importante).
Luego, en el archivo global style.scss de su proyecto> cree un selector que coincida con su contenedor modal> debajo del selector: agregue una línea que @ importe algún archivo (no agregue extensión)
style.scss
fuente
Según lo descrito por usted en el problema, desea heredar el CSS del componente primario dentro del componente secundario. Por lo tanto, supongo que tiene los mismos elementos HTML en los componentes primarios y secundarios y no desea duplicar su CSS.
Como no podemos replicar su problema y no ha creado ninguna instancia de stackblitz. Sugeriría una mejor alternativa que funcionará. Por favor encuéntrelo a continuación:
Podemos especificar múltiples URL CSS dentro de la
styleUrls
propiedad del@Component
objeto de metadatos del decorador. Por lo tanto, le sugiero que pase también la URL del archivo de estilo principal.He creado un stackblitz básico que muestra dónde estoy accediendo al CSS del componente principal: https://stackblitz.com/edit/angular-jhewzy
Archivo css del componente primario (app.component.css): estoy especificando que el color de fondo de la
p
etiqueta dentro del primario debe ser amarillo. Quiero heredar esto en el componente hijo.A continuación se muestra el componente CSS secundario (hello.component.css)
Como desea utilizar el componente primario dentro del componente secundario, simplemente use la ruta de URL de estilo en la propiedad styleUrls
Espero que te ayude.
fuente