Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing Components in Angular 2

When I started using Angular 2 I had the idea that the main reason to create components is because you can reuse them. EG:

<custom-button id="button1">button 1</custom-button>
<custom-button id="button2">button 2</custom-button>

Is it the case that this is a large reason to go with angular 2 and components in a web app, and it can be done?

I haven't found a resource that specifically answers my question about how to do this.

I'd like to create a button, and an input, the 2 most basic and commonly used html elements, and make them reusable.

I tried to make a button component and reuse it.

I tried to use it in an html template like this:

<custom-button>some text</custom-button>
<custom-button>different text</custom-button>

However the text did not show up on the button. Can this be done?

Another thing I'm wondering about is unique html id's when doing this. Am I able to add a unique html id attribute to each instance?

Maybe like:

<custom-button id="display-bikes">bikes</custom-button>
<custom-button id="display-helmets">helmets</custom-button>

And then I can do some specific css using the unique id of the element?

That's all I want to know, and how to do it.

However here is the rest of my code involved:

component:

import { Component } from '@angular/core';
@Component({
    selector: 'custom-button',
    templateUrl: 'app/shared/button.component.html',
    styleUrls: ['app/shared/button.component.css']
})
export class ButtonComponent { }

css:

button {
  font: 200 14px 'Helvetica Neue' , Helvetica , Arial , sans-serif;
  border-radius: 6px;
  height: 60px;
  width: 280px;
  text-decoration: none;
  background-color: $accent;
  padding: 12px;
  color: #FFF;
  cursor: pointer;
}

button:focus {
    outline:0 !important;
}

html:

<button md-raised-button type="button" class="btn text-uppercase flex-sm-middle">
try now <!-----lets get rid of this and let the client decide what text to display somehow???
</button>
like image 969
BeniaminoBaggins Avatar asked Aug 26 '16 22:08

BeniaminoBaggins


People also ask

Can I reuse component in angular?

Introduction to Reusable Angular Components Every time you use a reusable component, you also have a parent component. This flexible content inside the reusable component comes from parent content and ends up in a dedicated slot inside the reusable component. So it is projected down to the parent component.

What is reusability components?

In React, a reusable component is a piece of UI that can be used in various parts of an application to build more than one UI instance. For instance, we can have a Button component that displays different texts on different pages.


3 Answers

"Can this be done?"

Yes! It's called transclusion or content projection and you can read about it in detail here.

Here's how:

In button.component.html:

<button>
    <ng-content></ng-content>
</button>

Then, whenever you put content inside of the tags for the component, like this: <custom-button id="display-bikes">bikes</custom-button>, the Angular 2 compiler will 'project' it into the component's template inbetween the ng-content tags. So ultimately, you'd get this at runtime:

<button>
    bikes
</button>

That's just a simple example. You can get really advanced with it and do things like project other components and have multiple <ng-content> outlets. Read about that at the blog linked above.

And then I can do some specific css using the unique id of the element?

Also, yes... though you wouldn't use the standard id attribute.

On your ButtonComponent:

import { Component, Input } from '@angular/core';
@Component({
  selector: 'custom-button',
  templateUrl: 'app/shared/button.component.html',
  styleUrls: ['app/shared/button.component.css']
})
export class ButtonComponent {
  @Input() styleId: string;

  //...
}

Say that button.component.css has two classes named class-one and class-two.

In button.component.html:

<button [ngClass]="{class-one: styleId === 'applyClassOne', class-two: styleId === 'applyClasstwo'}">
    <ng-content></ng-content>
</button>

Then you bind to the Input property in the parent like so:

<custom-button [styleId]="'applyClassOne'"></custom-button>
<custom-button [styleId]="'applyClassTwo'"></custom-button>

There are other ways of applying styles dynamically, but this one is the simpliest given that there are only two classes to choose from.

like image 104
ABabin Avatar answered Nov 15 '22 21:11

ABabin


You can achieve this by using @Input decorator. You can read more about it here. First, in your ButtonComponent, add a variable which will display button name, like this:

export class ButtonComponent {

    @Input() buttonName: string;

}

Note: You need to import Input decorator: import { Input } from '@angular/core';

Then, in html use two-way data binding (interpolation) to display button value:

<button md-raised-button type="button" class="btn text-uppercase flex-sm-middle">
    {{buttonName}}
</button>

And, finally, when you want to display button component, you can give button a name with a simple attribute value:

<custom-button buttonName="First Button"></custom-button>
<custom-button buttonName="Second Button"></custom-button>
<custom-button buttonName="Third Button"></custom-button>

I tried to keep this as simple as possible, feel free to ask questions if you encounter any problems.

like image 33
Stefan Svrkota Avatar answered Nov 15 '22 21:11

Stefan Svrkota


You really should not bother writing specific CSS that depends on the ID of your component, this is not necessary.

Each component is encapsulated (by default). The encapsulation uses the Shadow DOM, or an emulation (default). For each component, you can choose one of the 3 encapsulation modes:

  • ViewEncapsulation.None -- no style encapsulation
  • ViewEncapsulation.Emulated -- the default, uses attributes to "encapsulate" the style
  • ViewEncapsulation.Native -- Uses Shadow DOM

Here is a good blog post about this topic: http://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html

like image 26
KnightB4 Avatar answered Nov 15 '22 23:11

KnightB4