简体   繁体   中英

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>

"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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM