Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - Styling Component's selector border css property

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>
enter image description here
like image 762
Rad Avatar asked Apr 01 '16 23:04

Rad


2 Answers

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();
  }
}
like image 60
Nikhil Shah Avatar answered Oct 05 '22 02:10

Nikhil Shah


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'
    }
}
like image 39
Rad Avatar answered Oct 05 '22 02:10

Rad