Reputation: 79
I have a checkbox-component which I'm using in a parent component. When the value has changed, I'm using an @Output()
to let the parent component know that the value has been updated.
My code is working but I'm using the checkbox-component many times in my project and I don't want to create it every time new function to set a new value of variable.
Here is the link to my code
My question is: How can I do it better? To prevent creating a new function onRoleChangeCheckboxX()
every time I have a new checkbox.
My stackblitz is just example, two extra functions doesn't bother me, but what about the case when I have to create 50 checkboxes.
Upvotes: 1
Views: 1290
Reputation: 2396
Here is a stackblitz of what I think you want? You need to create an array for your checkboxes
checkboxes = [
{
name: 'First checkbox',
value: false
},
{
name: 'Second checkbox',
value: false
},
]
Use the *ngFor to have a generic html that you don't need to edit when you add another checkbox to your array
<app-checkbox *ngFor="let box of checkboxes; let i = index"
[checkboxName]="box.name"
[checkboxData]="box.value"
(toggle)="onRoleChangeCheckbox($event, i)"></app-checkbox>
Then your onRoleChangeCheckbox()
function can become generic and update your array using an index
onRoleChangeCheckbox(ev, index) {
this.checkboxes[index].value = ev;
}
This method should reduce a lot of your repeated code since you only need to add new checkboxes to an array.
Upvotes: 1
Reputation: 1350
May be this is not the better approach but it may work in some cases like this , there will be one emit handler in all cases.
import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
@Component({
selector: "app-checkbox",
templateUrl: "./checkbox.component.html",
styleUrls: ["./checkbox.component.css"]
})
export class CheckboxComponent implements OnInit {
@Input() checkboxName;
@Input() checkboxData:any;
@Input() checkBoxLinkedProp:any; // added another property it is the name of the property in the parent component you are updating
@Output() toggle: EventEmitter<any> = new EventEmitter<any>(); // emit a object instead of bool
constructor() {}
ngOnInit() {}
onToggle() {
const checkedOption = this.checkboxData;
this.toggle.emit({checked:checkedOption , checkBoxLinkedProp: this.checkBoxLinkedProp });
}
}
app.component.html [checkBoxLinkedProp] = "'checkbox1Value'" -- i am passing the prop name as string to child checkbox component. and on toggle a single method is called (toggle)="onRoleChangeCheckbox($event)"
this.toggle.emit will emit object with the back with string prop we passed
<app-checkbox [checkboxName]='checkbox1' [checkboxData]='checkbox1Value'
[checkBoxLinkedProp] = "'checkbox1Value'"
(toggle)="onRoleChangeCheckbox($event)"></app-checkbox>
<app-checkbox [checkboxName]='checkbox2' [checkboxData]='checkbox2Value' (toggle)="onRoleChangeCheckbox($event)"
[checkBoxLinkedProp] = "'checkbox2Value'"
></app-checkbox>
app.component.ts onRoleChangeCheckbox({checkBoxLinkedProp , checked}) this method will take property name we passed as string from emit event and set that state of class.
import { Component, VERSION } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
checkbox1 = 'First checkbox';
checkbox1Value = false;
checkbox2 = 'Second checkbox';
checkbox2Value = false;
onRoleChangeCheckbox({checkBoxLinkedProp , checked}) {
this[checkBoxLinkedProp] = checked; // property name that passed to child , is received in this emit event and as this will be set
console.log(this.checkbox1Value , checkBoxLinkedProp); // tested value for 1st checkbox
}
}
Upvotes: 1
Reputation: 1870
its hard for me to tell exactly what you want, but if you are using eventEmitter & Output, you can Emit a complex json obj with a single emit statement and send as much data as you want to the parent:
@Output() messageEvent = new EventEmitter<any>();
var obj = { check1: true, check2: false, check3: false }
this. messageEvent.emit(obj);
Upvotes: 1