I am trying to create a component in Angular 5 that will house a reusable template for a button. In different parts of my app buttons will call different functions, so I would like to be able to tell the given instance of the button what function to call. I know I could create an HTML tag for a button wherever I need it, but I was hoping I could create a reusable component so I can ensure formatting is consistent throughout the app.
Error
Got interpolation ({{}}) where expression was expected at column 0 in
[{{functioncall}}]
Component
<div id = "button">
<button type="button" class= "btn" (click) ="{{functioncall}}" >{{label}}</button>
</div>
And HTML
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-button',
templateUrl: './button.component.html',
styleUrls: ['./button.component.css']
})
export class ButtonComponent implements OnInit {
@Input() label:string;
@Input() functionCall:string;
constructor() { }
ngOnInit() {
}
}
There are two main ways to create reusable components in Angular: Pass inputs to the component, passing the necessary data to the component used for rendering and configuring the component. This normally involves iterating over the provided data and follow a convention for how to render the data.
Introduction to Reusable Angular ComponentsEvery 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.
Angular was designed to advance code reusability. Reusable components are those react components that can be used multiple times in your application. As a result, they need to be generic enough so that it's free from complex business logic.
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.
you have to use the @Output
decorator to emit some event (from child to parent)
button.component.ts:
@Input() label: string;
@Output() onClick = new EventEmitter<any>();
onClickButton(event) {
this.onClick.emit(event);
}
button.component.html:
<div id = "button">
<button type="button" class= "btn" (click)="onClickbutton($event)" >{{label}}</button>
</div>
parent.component.ts
label = "button label"
functioncall(event) {
console.log('functioncall', event);
}
parent.component.html
<app-button (onClick)="functioncall($event)" [label]="label"></app-button>
See example: https://stackblitz.com/edit/angular-gghsax
In addition to @miladfm answer, I'd recommend using the <ng-content></ng-content>
directive here to pass content through instead of pulling in {{label}}
, assigning the @Output
decorator to click
instead of onClick
, and using the MouseEvent
type instead of any
. Using these changes will allow the button component to behave syntactically more like a native button when it's consumed:
button.component.ts
...
@Output() click = new EventEmitter<MouseEvent>();
onClickButton(event) {
this.onClick.emit(event);
}
...
button.component.html
<div id = "button">
<button type="button" class="btn" (click)="onClickbutton($event)">
<ng-content></ng-content>
</button>
</div>
parent.component.ts
...
functioncall(e: MouseEvent) {
// do stuff
}
...
parent.component.html
<app-button (click)="functioncall($event)">Your Label Here</app-button>
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