Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PrimeNG Element not scoped, can't be styled with default Angular 2 ViewEncapsulation (Emulated)

I'm trying to use the styleUrls property when declaring my Angular 2 component to take advantage of View Encapsulation but there seems to be a problem when elements get inserted into the DOM after Angular has its completed initialization.

My situation is with a PrimeNG paginator that I currently can't style since it doesn't get applied a scope by Angular.

See below the <p-datatable> element has a scope (it existed in the original markup) but <p-paginator> does not (was added to DOM after the fact).

enter image description here

Therefore the style inserted by Angular into HEAD does not match my elements:

<style>
    p-datatable[_ngcontent-xnm-4] p-paginator[_ngcontent-xnm-4]:not(:first-child) {
    display: none;
}
</style>

Is this a limitation of view encapsulation in Angular 2 or is there a way to have it "re-scope" the DOM on demand?

edited for typo and clarified title

like image 741
BlazingFrog Avatar asked Jul 26 '16 20:07

BlazingFrog


1 Answers

As you noticed this is because of the Shadow DOM and the style scoping it provides. Your template only contains the the p-datatable which correctly gets scoped, but its child elements that are added after the fact are NOT scoped. In order to apply your custom styling you can choose two approaches.

Solution 1 - Special Selectors (Recommended)

I personally recommend this as you can still maintain view encapsulation (Shadow DOM). We can still target our component level templates that use PrimeNG by using the :host and /deep/ selectors as such

:host /deep/ .ui-paginator-bottom {
  display: none;
}

What this does is force a style down through the child component tree into all the child component views so even though the p-datatable is the only tag present in your component's own template, the style will still be applied as it is a child to the component in the DOM.

Solution 2 - Disable View Encapsulation

At the component level you can disable the View Encapsulation by setting it to ViewEncapsulation.None as such

...
import { ..., ViewEncapsulation } from '@angular/core';

@Component {
...
encapsulation: ViewEncapsulation.None,
}
like image 154
AhmedBM Avatar answered Oct 18 '22 00:10

AhmedBM