web-dev-qa-db-fra.com

Angular 2 - Style innerHTML

Je reçois des morceaux de codes HTML à partir d'appels HTTP. Je mets les blocs HTML dans une variable et l'insère sur ma page avec [innerHTML] mais je ne peux pas styler le bloc HTML inséré. Quelqu'un a-t-il une suggestion sur la façon dont je pourrais atteindre cet objectif?

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

Le code HTML que je souhaite styler est le bloc contenu dans la variable "calendar".

142
Jakob Svenningsson

mise à jour 2 ::slotted

::slotted est maintenant supporté par tous les nouveaux navigateurs et peut être utilisé avec `ViewEncapsulation.ShadowDom

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

mise à jour 1 :: ng-deep

/deep/ était obsolète et remplacé par ::ng-deep.

::ng-deep est également déjà marqué comme obsolète, mais il n’ya pas encore de remplacement disponible.

Lorsque ViewEncapsulation.Native est correctement pris en charge par tous les navigateurs et prend en charge le style au-delà des limites DOM ombre, ::ng-deep sera probablement abandonné.

original

Angular ajoute toutes sortes de classes CSS au code HTML ajouté au DOM pour émuler une encapsulation CSS DOM pour éviter les styles d'insertion et de retrait de composants. Angular réécrit également le CSS que vous ajoutez pour correspondre à ces classes ajoutées. Pour le HTML ajouté à l'aide de [innerHTML], ces classes ne sont pas ajoutées et le CSS réécrit ne correspond pas.

Pour contourner le problème, essayez

  • pour CSS ajouté au composant
/* :Host /deep/ mySelector { */
:Host ::ng-deep mySelector { 
  background-color: blue;
}
  • pour CSS ajouté à index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
  background-color: green;
}

>>> (et l'équivalent/deep/ mais /deep/ fonctionne mieux avec SASS) et ::shadow ont été ajoutés dans la version 2.0.0-beta.10. Ils sont similaires aux combinateurs shadow DOM CSS (qui sont obsolètes) et ne fonctionnent qu'avec encapsulation: ViewEncapsulation.Emulated qui est la valeur par défaut dans Angular2. Ils fonctionnent probablement aussi avec ViewEncapsulation.None mais ne sont alors ignorés que parce qu'ils ne sont pas nécessaires. Ces combinateurs ne sont qu'une solution intermédiaire jusqu'à ce que des fonctionnalités plus avancées pour le style multi-composants soient prises en charge.

Une autre approche consiste à utiliser

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

pour tous les composants qui bloquent votre CSS (dépend de l'endroit où vous ajoutez le CSS et du HTML que vous souhaitez styler - peut être tous les composants de votre application)

Mettre à jour

Exemple Plunker

275
Günter Zöchbauer

Si vous essayez de styler des éléments HTML ajoutés dynamiquement dans un composant Angular, cela peut être 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(), '')
}

Mon hypothèse est que la convention pour cet attribut n'est pas toujours stable entre les versions de Angular, de sorte que l'on pourrait rencontrer des problèmes avec cette solution lors de la mise à niveau vers une nouvelle version de Angular (bien que la mise à jour de cette solution serait probablement trivial dans ce cas).

0
Trevor