Eu tenho componente pai e componente filho. Componente filho criado como um componente modal. Então, eu incluí o seletor de componente filho no componente pai e defini que o encapsulamento de exibição é nenhum, de modo que ele leve o componente pai css e tudo e está funcionando também, mas o componente pai tem o id do papel que aplica #paper id aplicando css libary de terceiros (rappidjs) (por Diagramação SVG). O mesmo componente filho tem o ID #dataMapper. mas aqui o css de terceiros não está recebendo porque o componente filho está definido como 'encapsulation: ViewEncapsulation.None'
. Se eu vou removê- encapsulation: ViewEncapsulation.None
lo está funcionando, mas modal não está funcionando. todos os modais carregando em vez de onclick. Como resolver este problema, por favor, aconselhe-me alguém.
Codificação:
TS do componente pai
@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 do componente pai
<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 do componente filho
<div class="app-modal">
<div class="app-modal-body">
<ng-content></ng-content>
</div>
</div>
<div class="app-modal-background"></div>
Ts de componente filho
@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 serviço 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();
}
}
Entre em contato se precisar de mais detalhes.
fonte
Respostas:
Por causa do seu modal. O modal é criado na parte superior do seu aplicativo (tag fora do corpo, se você procurar o invólucro modal ao inspecioná-lo.)
É a Modal porque a estrutura dom não está sincronizada com a estrutura do componente ng
Então, por que o modal funciona com ng
Encapsulation
? Porque o seu serviço modal pode lidar com isso.Mas o arquivo CSS de terceiros não faz parte da sua configuração de compilação angular (ou seja, apenas sass, scss funciona). Portanto, ele ignora qualquer
.css
importação mesmo.Para resolvê-lo, você pode aplicar o .css globalmente. Ou, se você tem medo de substituir outros estilos globais, renomeie o arquivo css para '_somefile.scss' (preste atenção ao traço '_', é importante).
Em seguida, no arquivo global style.scss do projeto> crie um seletor que corresponda ao seu wrapper modal> abaixo do seletor: adicione uma linha que importe algum arquivo (não adicione extensão)
style.scss
fonte
Conforme descrito por você no problema, você deseja herdar o css do componente pai dentro do componente filho. Então, suponho que você esteja tendo os mesmos elementos HTML nos componentes pai e filhos e não queira duplicar seu css.
Como não conseguimos replicar seu problema e você não criou nenhuma instância do stackblitz. Eu sugeriria uma alternativa melhor que funcione. Encontre-o abaixo:
Podemos especificar vários URLs CSS dentro da
styleUrls
propriedade do@Component
objeto de metadados do decorador. Então, eu sugiro que você passe o URL do arquivo de estilo pai também.Eu criei um stackblitz básico mostrando onde estou acessando o CSS do componente pai: https://stackblitz.com/edit/angular-jhewzy
Arquivo CSS do componente pai (app.component.css) - Estou especificando a cor de plano de fundo da
p
marca dentro do pai deve ser amarela. Eu quero herdar isso no componente filho.Abaixo está o CSS filho do componente (hello.component.css)
Como você deseja usar o componente pai dentro do componente filho, use o caminho do URL do estilo na propriedade styleUrls
Espero que ajude você.
fonte