Update: In my comment bellow you can find a zipped project on Google drive. Can anyone make a Plunker (I have never done it - what needs to be changed, any article/blog explaining this change).
I have a SearchComponent
which extends BaseComponent
and I am passing ElementRef
down to BaseComponent
so that BaseComponent
can add a border style to SearchComponent
's selector tag: auction-search
.
Basically I want to draw a border for all components (that extend BaseComponent
) on a page, so I can easily identify them.
However it seems that the width of auction-search
tag is auto (I don't know if this is 0px based on the CSS box in the picture below.
Using Chrome Tools inspection window when I add a div element with the same content and style below auction-search element (as shown in the picture below), I can then see a proper border and a real width is displayed.
So the question is how to give a component's selector a proper width so it can become a normal container like a DIV? Add position: absolute??
I played with adding ...
style.border = '8px solid green';position:absolute
and I got the bounding border, however that affected the next div element which will have text overlapping the component's text.
I believe I cannot use host property of the base component because the decorator's properties are not inherited. Can someone confirm?
What is the easiest way to propagate the same change in CSS e.g. throughout all components?
host: {
'style': 'border: 8px solid green'
}
Thanks, Rad
Here is the code for my 2 components:
//base-component.ts
import {Component, OnInit, ElementRef} from "angular2/core";
@Component({selector: 'base-component'})
export class BaseComponent implements OnInit
{
constructor(private _elementRef: ElementRef){
_elementRef.nativeElement.style.border = '4px solid green';
}
//auction-search.ts
import {Component, ElementRef} from 'angular2/core';
import {BaseComponent} from "../base/base-component";
@Component({
selector: 'auction-search',
templateUrl: 'app/components/search/search.html'
})
export default class SearchComponent extends BaseComponent
{
constructor(private _elementRef: ElementRef)
{
super(_elementRef);
}
}
app/components/search/search.html
<p>
Some text with <br>
Another line
</p>
app/components/application/application.html
<div class="col-md-3">
<auction-search></auction-search>
</div>
I don't understand your problem exactly but this might help you.
host:{
'style': 'display: block;',
}
Take a look here
or
UPDATE:
As you want to apply styles through program only, I have made this
http://plnkr.co/edit/9LvtDq7xei0WEVzAelHv?p=preview
which uses directive
concept of Angular2. With that I have used ViewChild
,exportAs
. In this example,my BaseClass
has some child components(more than one child components). By using directive
and elementRef
, you can target individual child component as you want.
Now you don't have to extent Baseclass
as you did in your demo.
import {Directive,Component,ViewChild} from 'angular2/core';
import {Component, OnInit, ElementRef} from 'angular2/core';
import {Directive,Component,ViewChild,ViewChildren,ElementRef,Renderer} from 'angular2/core';
import {SearchComponent} from 'app/searchComponent';
//import {MyCustomDirective} from 'app/directive';
@Directive({
selector:'[my-custom-directive]',
exportAs:'customdirective'
})
class MyCustomDirective{
constructor(private _renderer:Renderer,private _el:ElementRef){
}
firstChildCmp(className:string,isAdd:boolean)
{
this._el.nativeElement.style.border = '2px solid orange';
}
secondChildCmp(className:string,isAdd:boolean)
{
this._el.nativeElement.style.border = '2px solid red';
}
thirdChildCmp()
{ console.log('firstChildCmp');
this._el.nativeElement.style.border = '2px solid blue';
}
}
@Component({
selector: 'my-app',
directives:[MyCustomDirective,SearchComponent],
template: `
<div>
<div >Some content here</div>
</div>
<div>
<auction-search #var1=customdirective my-custom-directive></auction-search>
<auction-search #var2=customdirective my-custom-directive></auction-search>
<auction-search #var3=customdirective my-custom-directive></auction-search>
</div>
`,
host:{
'style': 'display: block;',
}
})
export class BaseComponent{
@ViewChild('var1') firstElement;
@ViewChild('var2') secondElement;
@ViewChild('var3') thirdElement;
constructor(private _elementRef: ElementRef){
_elementRef.nativeElement.style.border = '4px solid green';
}
ngAfterViewInit(){
this.firstElement.firstChildCmp();
this.secondElement.secondChildCmp();
this.thirdElement.thirdChildCmp();
}
}
Here is the solution for my case. @micronyks Thanks for stepping in. I cannot use host property because it is not inheritable property.
I also wanted to know if there is an easier way to spread some style changes throughout all components without using inheritence?. So basically I want to avoid changing the signature of component's class declaration.
//base-component.ts
import {Component, OnInit, ElementRef, Renderer} from "angular2/core";
@Component({
selector: 'base-component'
/* This won't work - no inheritance of component decorator properties (Am I right here?)
,
host: {
'style': 'display:block'
}
*/
})
export class BaseComponent {
constructor(elementRef: ElementRef, renderer: Renderer)
{
//first way
renderer.setElementStyle(elementRef.nativeElement, 'border', '1px solid blue');
renderer.setElementStyle(elementRef.nativeElement, 'display', 'block');
//second way
//elementRef.nativeElement.style.border = '1px solid blue'
//elementRef.nativeElement.style.display = 'block'
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With