How to create a fully dynamic button in angular 6?
Here you need to property binding and event binding like below.
app.component.html
<app-button description="Dyanmic Button"
class="button" (callFunction)="onButtonClicked($event)" >
</app-button>
app.component.ts
export class AppComponent {
name = 'Angular';
onButtonClicked(event) {
console.log(event); // handle button clicked here.
}
}
button.component.html
<div [formGroup]="group">
<button [type]="type" [class]="class" (click)="onClick($event)">
{{ description }}
</button>
</div>
button.component.ts
import { Component, OnInit, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-button',
templateUrl: './button.component.html',
styleUrls: ['./button.component.css'],
encapsulation: ViewEncapsulation.None
})
export class ButtonComponent implements OnInit {
@Input() group: FormGroup;
@Input() type: string;
@Input() description: string;
@Input() class: string;
@Input() data: string;
@Output() callFunction = new EventEmitter();
constructor() { }
ngOnInit() {
this.group = new FormGroup({
firstName: new FormControl()
});
}
onClick(event) {
this.callFunction.emit('I am button');
}
}
Here is solution on stackblitz
I was able to make this example work:
Child Component
export class HelloComponent implements OnChanges {
@Input() name: string;
@Input() callFunction: Function; // NOTE: The data type here
// Just some code to call the function
ngOnChanges() {
// Ensure the @Input property has been set before trying to call it.
if (this.callFunction) {
this.callFunction();
}
}
}
Parent Template
<hello
name="{{ name }}"
[callFunction]="myCallBackFunction"></hello>
Notice that is it using property binding with []
and referencing the function in the parent's component code.
Parent Component
export class AppComponent {
name = 'Angular';
myCallBackFunction() {
console.log('called the function')
}
}
I have a working stackblitz here: https://stackblitz.com/edit/angular-function-input-property-deborahk
When you run the code you will see "called the function" in the console.
I have not used dynamically loaded components, so not sure how that impacts how this works. But wanted to provide the basic syntax that does work in a "normal" component.
UPDATE
Setting an @Input
property like this:
@Input() callFunction: Function;
Cannot be bound like this:
<button type="{{ type }}" class="{{ class }}" (click)="{{callFunction}}">
Input properties are set using property binding:
<button type="{{ type }}" class="{{ class }}" [callFunction]="someFunction">
If you want to use event binding, you'll need to define an @Output
property.