Angolare 2 - styling HTML interno


170

Ricevo pezzi di codici HTML da chiamate HTTP. Ho inserito i blocchi HTML in una variabile e li ho inseriti nella mia pagina con [innerHTML] ma non riesco a definire il blocco HTML inserito. Qualcuno ha qualche suggerimento su come potrei raggiungere questo obiettivo?

@Component({selector: 'calendar',
template: '<div [innerHTML]="calendar"></div>',
providers:[HomeService], 
styles: [` 
h3 {color:red;}
`})

L'HTML che voglio modellare è il blocco contenuto nella variabile "calendario".


Lo stile da dove? Dall'interno del componente o dagli stili aggiunti a index.html?
Günter Zöchbauer,

cosa intendi con can not style the inserted HTML block? Mostraci cosa hai fatto per questo con un piccolo frammento di codice.
Micronyks,

Ho aggiornato il mio post con uno snippet di codice! :) grazie
Jakob Svenningsson,

1
Ho aggiunto un link Plunker alla mia risposta
Günter Zöchbauer il

@ GünterZöchbauer cosa succede se i codici HTML hanno CSS in linea? come sarà reso?
Iniravpatel

Risposte:


320

aggiornamento 2 ::slotted

::slotted è ora supportato da tutti i nuovi browser e può essere utilizzato con ViewEncapsulation.ShadowDom

https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

aggiornamento 1 :: ng-deep

/deep/è stato deprecato e sostituito da ::ng-deep.

::ng-deep è anche contrassegnato come obsoleto, ma non è ancora disponibile alcun sostituto.

Quando ViewEncapsulation.Nativeè adeguatamente supportato da tutti i browser e supporta lo stile oltre i confini del DOM ombra, ::ng-deepverrà probabilmente interrotto.

originale

Angular aggiunge tutti i tipi di classi CSS all'HTML che aggiunge al DOM per emulare l'incapsulamento CSS dell'ombra DOM per prevenire stili di bleeding dentro e fuori dai componenti. Angular riscrive anche il CSS che aggiungi per abbinare queste classi aggiunte. Per HTML aggiunto usando [innerHTML]queste classi non vengono aggiunti e il CSS riscritto non corrisponde.

Come soluzione alternativa, prova

  • per CSS aggiunto al componente
/* :host /deep/ mySelector { */
:host ::ng-deep mySelector { 
  background-color: blue;
}
  • per CSS aggiunto a index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
  background-color: green;
}

>>>(e l'equivalente /deep/ma /deep/funziona meglio con SASS) e ::shadowsono stati aggiunti in 2.0.0-beta.10. Sono simili ai combinatori CSS DOM shadow (che sono obsoleti) e funzionano solo con encapsulation: ViewEncapsulation.Emulatedil valore predefinito in Angular2. Probabilmente funzionano anche con, ViewEncapsulation.Nonema vengono ignorati solo perché non sono necessari. Questi combinatori sono solo una soluzione intermedia fino a quando non saranno supportate funzionalità più avanzate per lo stile tra componenti.

Un altro approccio è usare

@Component({
  ...
  encapsulation: ViewEncapsulation.None,
})

per tutti i componenti che bloccano il tuo CSS (dipende da dove aggiungi il CSS e dove si trova lo stile HTML che desideri - potrebbero essere tutti i componenti nella tua applicazione)

Aggiornare

Esempio Plunker


6
Solo una nota per chiunque, questo non funziona né con node-sass, né con styleUrl. Solo negli stili: [...]
thouliha,

12
Con SASS utilizzare /deep/invece di>>>
Günter Zöchbauer l'

1
Non puoi avere direttive o componenti nei contenuti aggiunti coninneeHTML
Günter Zöchbauer

1
Se l'HTML fornito dalla chiamata HTTP è grande e ha CSS in linea come sarà possibile in quanto non ho gli stili predefiniti, lo ottengo solo dal CSS in linea @ GünterZöchbauer
iniravpatel

1
Hai salvato la giornata in Angular 8! Grazie. È difficile ottenere la domanda giusta per trovare questa risposta!
Pianoman,

12

La semplice soluzione che devi seguire è

import { DomSanitizer } from '@angular/platform-browser';

constructor(private sanitizer: DomSanitizer){}

transformYourHtml(htmlTextWithStyle) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlTextWithStyle);
}

2

Se stai cercando di dare uno stile agli elementi HTML aggiunti dinamicamente all'interno di un componente Angolare, questo potrebbe essere utile:

// inside component class...

constructor(private hostRef: ElementRef) { }

getContentAttr(): string {
  const attrs = this.hostRef.nativeElement.attributes
  for (let i = 0, l = attrs.length; i < l; i++) {
    if (attrs[i].name.startsWith('_nghost-c')) {
      return `_ngcontent-c${attrs[i].name.substring(9)}`
    }
  }
}

ngAfterViewInit() {
  // dynamically add HTML element
  dynamicallyAddedHtmlElement.setAttribute(this.getContentAttr(), '')
}

La mia ipotesi è che la convenzione per questo attributo non sia garantita stabile tra le versioni di Angular, quindi si potrebbero riscontrare problemi con questa soluzione durante l'aggiornamento a una nuova versione di Angular (anche se l'aggiornamento di questa soluzione sarebbe probabilmente banale in quanto Astuccio).


2

Riceviamo frequentemente contenuti dal nostro CMS come [innerHTML]="content.title". styles.scssInseriamo le classi necessarie nel file root dell'applicazione anziché nel file scss del componente. Il nostro CMS elimina di proposito gli stili in linea, quindi dobbiamo aver preparato delle classi che l'autore può usare nei loro contenuti. Ricorda che l'utilizzo {{content.title}}nel modello non renderà html dal contenuto.


-3

Se si utilizza sass come preprocessore di stile, è possibile tornare al compilatore Sass nativo per la dipendenza dev:

npm install node-sass --save-dev

In modo da poter continuare a utilizzare / deep / per lo sviluppo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.