Ich habe übergeordnete Komponente und untergeordnete Komponente. Untergeordnete Komponente, die als modale Komponente erstellt wurde. Also habe ich den Selektor für untergeordnete Komponenten in die übergeordnete Komponente aufgenommen und die Ansichtskapselung so eingestellt, dass keine übergeordnete Komponenten-CSS und alle verwendet werden. Es funktioniert auch, aber die übergeordnete Komponente hat die # paper-ID, die eine libary-CSS von Drittanbietern (rappidjs) anwendet (für SVG-Diagramm). Die gleiche wie die untergeordnete Komponente hat die ID #dataMapper. aber hier nimmt die Drittanbieter-CSS nicht, weil die untergeordnete Komponente auf gesetzt ist 'encapsulation: ViewEncapsulation.None'
. Wenn ich entfernen werde, encapsulation: ViewEncapsulation.None
funktioniert es, aber Modal funktioniert nicht. Alle Modalitäten werden geladen, anstatt auf einen Klick zu klicken. Wie Sie dieses Problem lösen können, beraten Sie mich bitte.
Codierung:
Übergeordnete Komponente 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 der übergeordneten Komponente
<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>
Untergeordnete Komponente HTML
<div class="app-modal">
<div class="app-modal-body">
<ng-content></ng-content>
</div>
</div>
<div class="app-modal-background"></div>
Untergeordnete Komponente 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');
}
}
Modaler Servicecode
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();
}
}
Bitte lassen Sie mich wissen, wenn weitere Details erforderlich sind.
quelle
Antworten:
Wegen deines Modals. Die Modal auf erstellt wird Anfang der App, (aus Body - Tag , wenn man sich für den modal - Wrapper durch Inspektion.)
Dies ist die modale Ursache dafür, dass die Dom-Struktur nicht mit der ng-Komponentenstruktur synchronisiert ist
Warum funktioniert das Modal mit ng
Encapsulation
? Weil Ihr modaler Dienst damit umgehen kann.Die CSS-Datei eines Drittanbieters ist jedoch nicht Teil Ihrer Winkelkompilierungskonfiguration (dh nur sass, scss funktioniert). Es ignoriert also alles,
.css
selbst wenn Sie es richtig importieren.Um dies zu lösen, können Sie die CSS-Datei global anwenden. Wenn Sie befürchten, dass andere globale Stile überschrieben werden , können Sie die CSS-Datei in '_somefile.scss' umbenennen (achten Sie auf den Bindestrich '_', dies ist wichtig.)
Dann unter der globalen Datei style.scss Ihres Projekts> Erstellen Sie einen Selektor, der Ihrem modalen Wrapper entspricht> unter dem Selektor: Fügen Sie eine Zeile hinzu, die @import somefile (keine Erweiterung hinzufügen)
style.scss
quelle
Wie von Ihnen in dem Problem beschrieben, dass Sie das CSS der übergeordneten Komponente innerhalb der untergeordneten Komponente erben möchten. Ich gehe also davon aus, dass Sie dieselben HTML-Elemente in übergeordneten und untergeordneten Komponenten haben und Ihr CSS nicht duplizieren möchten.
Da wir Ihr Problem nicht replizieren können und Sie keine Stackblitz-Instanz erstellt haben. Ich würde eine bessere Alternative vorschlagen, die funktionieren wird. Bitte finden Sie es unten:
Wir können mehrere CSS-URLs in der
styleUrls
Eigenschaft des@Component
Decorator-Metadatenobjekts angeben . Daher würde ich vorschlagen, dass Sie auch die übergeordnete Stildatei Url übergeben.Ich habe einen einfachen Stackblitz erstellt, der zeigt, wo ich auf CSS der übergeordneten Komponente zugreife: https://stackblitz.com/edit/angular-jhewzy
CSS-Datei der übergeordneten Komponente (app.component.css) - Ich gebe an, dass die Hintergrundfarbe des
p
Tags im übergeordneten Element gelb sein soll. Ich möchte dies in der untergeordneten Komponente erben.Unten finden Sie die untergeordnete Komponente CSS (hello.component.css).
Wenn Sie die übergeordnete Komponente in der untergeordneten Komponente verwenden möchten, verwenden Sie einfach den Stil-URL-Pfad in der styleUrls-Eigenschaft
Ich hoffe es hilft dir.
quelle