I know this is an old question but I cant find a simple answer and it seems so strange.
I have a father component with its own html and several component that extends this one.
I need something like this:
Father's HTML template
<p class="father"> somethings </p>
<child-component></child-component> <-- some kind of angular tag
class ChildComponent extends FatherComponent
<p> Im a Child </p>
Result rendering Child
<p class="father"> somethings </p>
<p> Im a Child </p>
Is this so hard to get?
UPDATE AS ASKED
#Component({
selector: 'BaseComponent',
templateUrl: 'BaseComponent.html',
})
export class BaseComponent implements OnInit
{
...
}
#Component({
selector : 'ChildBaseComponent ',
templateUrl : 'ChildBaseComponent .html',
})
export class ChildBaseComponent extends BaseComponent
{
....
}
I think what you're looking for here is content projection. You can find plenty of articles about this topic. I modified you examples slightly
#Component({
selector: 'BaseComponent',
template: `
<p class="father"> somethings </p>
<ng-content></ng-content>
`,
})
export class BaseComponent implements OnInit
{
...
}
#Component({
selector : 'ChildBaseComponent',
templateUrl : `
<BaseComponent><p> Im a Child </p></BaseComponent>`,
})
export class ChildComponent
{
#ViewChild(BaseComponent) public baseComponent: BaseComponent
}
The thing is Angular doesn't inherit metadata of the parent class, it overrides it.
There plenty of tools angular provides to deal with code sharing. You can always access your parent component from the child thanks to ViewChild decorator.
And as the answer to your question - no, there is no such tag.
Related
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
})
I have a Component, DataGrid, which represents a table with expandable rows. Each row, when expanded, shows a child DataGrid table, which is very similar to the parent DataGrid component.
Therefore I defined a base class DataGridComponent, from which the child inherits the both the component and the template. however, I need to change one of the tags in the child's template. Do I have to rewrite the entire template, or could I just point the templateUrl to the parent's template and programmatically change the one html tag that I need to change?
Minimal Example:
base.component.ts
#Component({
selector: 'datagrid',
templateUrl: 'datagrid.component.html'
})
export class DataGridComponent {
childEnabled:boolean = true;
// stuff
}
datagrid.component.html
<div>...</div>
<div *ngIf="childEnabled">
<childgrid
[options]="childOptions"
>
</childgrid>
</div>
child.component.ts
#Component({
selector: 'childgrid',
templateUrl: 'datagrid.component.html' // <-- POINT TO BASECLASS TEMPLATE
})
export class ChildGridComponent extends DataGridComponent{
}
childgrid.component.html // <-- HOW THE (REAL) TEMPLATE SHOULD BE
<div>...</div>
<div *ngIf="childEnabled">
<grandchildgrid
[options]="childOptions"
>
</grandchildgrid>
</div>
grandchild.component.ts
#Component({
selector: 'grandchildgrid',
templateUrl: 'datagrid.component.html' // <-- POINT TO BASECLASS TEMPLATE
})
export class GrandChildGridComponent extends DataGridComponent{
constructor() {
super();
childEnable=false;
}
}
grandchildgrid.component.html // <-- HOW THE (REAL) TEMPLATE SHOULD BE
<div>...</div>
<div *ngIf="childEnabled">
<grandchildgrid
[options]="childOptions"
>
</grandchildgrid>
</div>
and so on until childEnabled is set to false. Is there any chance to do something like this and is it something that would make sense from an angularly point of view? Would ng-content be of any help in this case?
The content of DataGrid can go into a separate component and that can be used as a template in both parent and child DataGrid.
Alternative option is to have the same tags and control behavior using different class and id for parent and child
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?
Anular 5: For clear structure of module i wanna make some AbstractParentComponent (that have reusable logic and template) and have possibility extend it:
#Component({
selector: 'app-parent',
template: ' //reusable header element with logic
*here we should have ability to change part of tamplate*
<ng-container *ngTemplateOutlet="customTemplate"> </ng-container>
//reusable footer element with logic
'
})
export class ParentComponent{
//logic impl
And i wanna ability create extended components that extend all parent logic but implement own part with custom template:
#Component({
selector: 'app-child',
template: '
//here i wanna extend parent template
/*something like*/ <ng-template #customTemplate>
//some template impl
</ng-template>'
})
export class ChildComponent extends ParentComponent{}
How it's possible to do ?
How about:
#Component({
selector: 'app-child',
template: '<app-parent></app-parent>'
})
export class ChildComponent extends ParentComponent{}
I started using angular 5 and I have a problem with binding css between the tag style from a variable in the component.ts.
So this is my code in component.ts:
export class AppComponent {
style = '.p-color{color: red;}';
}
and this is my html code:
<style>{{style}}</style>
Anyone have any ideas how to solve it?
One question in advance: Why do you want to do that? I don't think that's the best approach for achieving your goal.
There are several other methods in Angular 4 to apply styles:
Class-selector
<p [class.color-red]="your-expression">Your text</p>
Host Binding
export class SongTrack {
//<host class="selected"></host>
#HostBinding('class.selected') selected = true;
//<host style="color: red;"></host>
#HostBinding('style.color') color = 'red';
}
Source: https://medium.com/google-developer-experts/angular-advanced-styling-guide-v4-f0765616e635
Set styles directly
<h1 [style.color]="titleStyle ? 'green' : 'pink'">
{{title}}
</h1>
Hope that helps :)
create file html and css include appcomponent
#Component({
selector:'all-page',
templateUrl:'./code.templet.html',
styleUrls: ['./color.component.css']
})
export class AppComponent
I needed to do the same thing and it worked for me
At your TS file:
import {ElementRef,Renderer2} from '#angular/core';
#Component({
...
})
export class Foo{
#ViewChild('css') element:ElementRef;
ngOnInit(){
element.nativeElement.innerHTML = '<style type="text/css"> Your css goes here </style>';
}
}
At your template:
<div #css>//style will be bind here</div>