diff --git a/packages/sitecore-jss-angular/src/components/placeholder.component.spec.ts b/packages/sitecore-jss-angular/src/components/placeholder.component.spec.ts
index f62e8db6a2..8e2145e3d0 100644
--- a/packages/sitecore-jss-angular/src/components/placeholder.component.spec.ts
+++ b/packages/sitecore-jss-angular/src/components/placeholder.component.spec.ts
@@ -34,6 +34,7 @@ class TestDownloadCalloutComponent {
@Component({
selector: 'test-home',
+ styles: [ 'sc-placeholder[name="page-content"] { background-color: red }' ],
template: `
@@ -167,6 +168,35 @@ describe('', () => {
});
}));
+ it('should copy parent style attribute', async(() => {
+ const component = nonEeDevData.sitecore.route;
+ const phKey = 'main';
+ comp.name = phKey;
+ comp.rendering = component;
+ fixture.detectChanges();
+
+ fixture.whenStable()
+ .then(() => {
+ fixture.detectChanges();
+
+ // let's grab the style name from the parent
+ let parentKey = '';
+ const homeComp = de.query(By.directive(TestHomeComponent));
+ const homeAttributes = homeComp.nativeElement.attributes;
+ if (homeAttributes.length) {
+ const parentAttribute = homeComp.nativeElement.attributes.item(0).name;
+ parentKey = parentAttribute.replace('_nghost-', '');
+ }
+
+ fixture.whenStable()
+ .then(() => {
+ fixture.detectChanges();
+ const downloadCallout = de.query(By.directive(TestDownloadCalloutComponent));
+ expect(downloadCallout.nativeElement.attributes.item(0).name).toEqual(`_ngcontent-${parentKey}`);
+ });
+ });
+ }));
+
it('should skip rendering unknown components', async(() => {
const phKey = 'main';
const route = {
diff --git a/packages/sitecore-jss-angular/src/components/placeholder.component.ts b/packages/sitecore-jss-angular/src/components/placeholder.component.ts
index 59c6a66236..f1e6e5c4b0 100644
--- a/packages/sitecore-jss-angular/src/components/placeholder.component.ts
+++ b/packages/sitecore-jss-angular/src/components/placeholder.component.ts
@@ -4,6 +4,7 @@ import {
ComponentFactoryResolver,
ContentChild,
DoCheck,
+ ElementRef,
EventEmitter,
Inject,
Input,
@@ -11,7 +12,9 @@ import {
KeyValueDiffers,
OnChanges,
OnDestroy,
+ OnInit,
Output,
+ Renderer2,
SimpleChanges,
Type,
ViewChild,
@@ -43,11 +46,12 @@ function getPlaceholder(rendering: ComponentRendering, name: string) {
`,
})
-export class PlaceholderComponent implements OnChanges, DoCheck, OnDestroy {
+export class PlaceholderComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
private _inputs: { [key: string]: any };
private _differ: KeyValueDiffer;
private _componentInstances: any[] = [];
private destroyed = false;
+ private parentStyleAttribute: string = '';
public isLoading = true;
@Input() name?: string;
@@ -76,9 +80,26 @@ export class PlaceholderComponent implements OnChanges, DoCheck, OnDestroy {
private differs: KeyValueDiffers,
private componentFactory: JssComponentFactoryService,
private changeDetectorRef: ChangeDetectorRef,
+ private elementRef: ElementRef,
+ private renderer: Renderer2,
@Inject(PLACEHOLDER_MISSING_COMPONENT_COMPONENT) private missingComponentComponent: Type
) { }
+ ngOnInit() {
+ // just to ensure the element exists
+ const elem = this.elementRef.nativeElement;
+
+ if (elem) {
+ const attributes: NamedNodeMap = elem.attributes;
+ for (let i = 0; i < attributes.length; i++) {
+ const attr: Attr | null = attributes.item(i);
+ if (attr && attr.name.indexOf('_ngcontent') !== -1) {
+ this.parentStyleAttribute = attr.name;
+ }
+ }
+ }
+ }
+
ngOnDestroy() {
this.destroyed = true;
this._componentInstances = [];
@@ -199,7 +220,14 @@ export class PlaceholderComponent implements OnChanges, DoCheck, OnDestroy {
const componentFactory =
rendering.componentFactory || this.componentFactoryResolver.resolveComponentFactory(rendering.componentImplementation);
- const componentInstance = this.view.createComponent(componentFactory, index).instance;
+ // apply the parent style attribute _ngcontent
+ // work-around for https://github.com/angular/angular/issues/12215
+ const createdComponentRef = this.view.createComponent(componentFactory, index);
+ if (this.parentStyleAttribute) {
+ this.renderer.setAttribute(createdComponentRef.location.nativeElement, this.parentStyleAttribute, '');
+ }
+
+ const componentInstance = createdComponentRef.instance;
componentInstance.rendering = rendering.componentDefinition;
if (this._inputs) {
this._setComponentInputs(componentInstance, this._inputs);