Styles are not getting applied to HTML injected via network call - html

In my angular 8.1.3 application, I am injecting HTML div, I want to apply styles to the classes used in that HTML payload.
But styles are not getting applied unless I put them in root level CSS of the project. (Which I dont want to do)
Sub-component.html
<div id="ImgBlock" class="col-xs-12">
<div> [innerHTML]="ImagePayload"></div>
</div>
here is my Sub-component.ts
#Component({
selector: 'SubComponent',
templateUrl: './SubComponent.html',
styleUrls: ['./SubComponent.scss'],
encapsulation: ViewEncapsulation.None
})
export class SubComponent implements OnInit, AfterViewInit {
public ImagePayload: string;
// Constructros and other functions
}
here is the parent component which creates an instance of sub-component and injects HTML payload in ImagePayload variable.
#Component({
selector: 'parentComponent',
templateUrl: './parentComponent.html',
styleUrls: ['./parentComponent.scss'],
encapsulation: ViewEncapsulation.None
})
export class parentComponent implements OnInit, OnDestroy {
showImage(data: Somedata) {
const dialog: DialogRef = this.dialogService.open({
title: 'recognise Image data ',
content: SubComponent,
});
const info = dialog.content.instance;
info.ImagePayload = data.challenge;
}
}
Here is a css style for class used in imagePayload variable.
input.Image_selection_checkbox {
width: 15px;
}
I applied the same style to
1) SubComponent.scss
2) parentComponent.scss
3) app.component.scss
(of parentCompoent)
4) style.scss of this particular sub-project
(Project have multiple sub-project as well)
but none of them are getting applied !
But when I put the same style in root style.scss (of the main project directory!)
It is getting applied.
I am having a limited idea about role of encapsulation. Is that a culprit?
what are the other issues?

Related

How to add SCSS to a component of an angular library

I've created a library in angular 6. The problem is that styling is not applied. Here is my code:
mycustom.component.html
<div class="cutom-div">
Hello
</div>
mycustom.component.ts
import { Component, OnInit } from "#angular/core";
#Component({
selector: "lib-mycustom",
templateUrl: "./mycustom.component.html",
styleUrls: ["./mycustom.component.scss"],
})
export class MycustomComponent implements OnInit {
constructor() {}
ngOnInit() {}
}
mycustom.component.scss
.custom-div {
background: red;
height: 20px;
}
This was supposed to be simple. But there's no styling applied. I inspected the element also:
What else I'm missing out here. Please point out my mistake.
I'm building the library normally:
ng build my-library and then cd dist\my-library>npm pack
https://angular.io/api/core/ViewEncapsulation#None
None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This mode is essentially the same as pasting the component's styles into the HTML.
#Component({
selector: "lib-mycustom",
templateUrl: "./mycustom.component.html",
styleUrls: ["./mycustom.component.scss"],
encapsulation: ViewEncapsulation.None, // <- This need use for global style
})

Angular styles not applying when insert component inside shadow-root

In my app, I use the widget which displays in shadow-root, and inside it has a div with an id where I need to insert my component. Like:
<widget>
#shadow-root (open)
....
<div id='container'> // need to insert component here // </div>
...
</widget>
For now, in test.html I have simple
<div #test>It works!</div>
In widget settings, I could get this <div id='container'></div> as parameter and pass it to my component, so test.ts looks like
#Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class Test implements OnInit, AfterViewInit {
#Input() container: HTMLDivElement,
#ViewChild('test', { static: true }) test: ElementRef;
ngAfterViewInit(): void {
const testElement = this.test.nativeElement;
container.appendChild(testElement);
}
}
The problem is that when it inserts to the shadow-root it doesn't see the styles from test.component.less. I tried :host{} :host ::ng-deep {} and it still doesn't work.
So my question is - is there a way to apply styles from test.component.less to my .html file, while it's inside shadow-root?
Would be really grateful for any help!
Maybe you need set view encapsulation to none
#Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
hope helped you.

Can I use an html tag as selector in ViewChildren

I want to make all <p> in the template have font-variant small-caps. Can I pass an html to ViewChildren? I have seen examples where template reference variables or components are passed but haven't seen an example where the selector passed to ViewChildren is an html tag or a css class.
template: `<p>
I am a static component
</p>
<p>
I am another para but I have an id (template reference variable) #pref. I got my blue color using ViewChild and Renderer2
</p>
<p>
All paragraphs are small-caps because using ViewChildren and Renderer2, the style was set to bold
</p>`
.ts file
import { Component,ViewChild, ViewChildren, QueryList,ElementRef,Renderer2,OnInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular';
#ViewChildren("p") paraList:QueryList<any>; /*I SUPPOSE I CANT DO THIS AS P IS INTERPRETED AS TEMPLATE REFERENCE VARIABLE AND NOT <P>*/
constructor(private renderer:Renderer2){
}
ngAfterViewInit(){ //QueryList becomes available now
this.paraList.forEach(para =>{this.renderer.addClass(para,'boldClass')})
}
}
css
.boldClass{
font-variant: small-caps;
}

Show elements from base component in derived component Angular 4/5

#Component({
selector: 'app-test-base',
templateUrl: '<button (click)="someMethod()">Button on Base Component</button>>',
styleUrls: ['./test-base.component.css']
})
#Component({
selector: 'app-derived',
templateUrl: './derived.component.html',
styleUrls: ['./derived.component.css']
})
export class derivedComponent extends baseComponent implements OnInit {...}
Is possible to inject this button on derived HTML component?
If i understood what you have/want..
You can call like so:
<app-test-base></app-test-base>
on your derived.component.html page, and your app-test-base components gets started up on your derived component. Do note that the someMethod method should be declared on the app-test-base and all the other logic for interacting with that page.. You can also pass Inputs and receive Outputs from this kind of behaviour.. but thats another story :3

Computationally bind styles in Angular

Using Angular5 - I know how it is possible to bind an HTML element's style to a Boolean value, but I can't find an explanation to do this for multiple styles at the same time.
ie. I have found something like this works fine:
[style.background]="r.favourite === true ? '#3f51b5' : 'white'"
However I am also wanting to change the color of my text to white at this point also... And I don't want to clutter my components with lots of [style.xxx] tags.
Is there a way I can dynamically bind to a CSS class to apply when r.favourite === true?
I have seen ways in which this can be done... However this assumes you are binding within the same file as such:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<button class="my-btn" [class.extraclass]="someProperty">Call to Action</button>
`,
styles: [`
.my-btn { font-size:1.7em; }
.extraclass { background: black; color: white; }
`]
})
export class AppComponent {
someProperty = true;
}
However my CSS is being stored in a shared file - such that I have a file structure like:
import { Component } from '#angular/core';
#Component({
selector: 'my-component',
styleUrls: ['./css/shared-styles.css']
template: `
<button class="my-btn" [class.extraclass]="someProperty">Call to Action</button>
`
})
export class MyComponent {
someProperty = true;
}
You can use NgClass.
<div [ngClass]="{'text-success':r.favourite ,'text-danger':!r.favourite}">
Where 'text-success' and 'text-danger' are classes you define.
Please refer to this great article about NgClass and NgStyle:
https://codecraft.tv/courses/angular/built-in-directives/ngstyle-and-ngclass/
Hope this helps