Reputation: 1704
I would like to set different methods to be called at the (click)
event. I created an array of dictionaries in the ts
-File:
headerElements = [
{
descriptor: "Name",
icon: "/assets/imgs/name-32.png",
cursor: "default",
event: "null"
},
{
descriptor: "Price",
icon: "/assets/imgs/description-32.png",
cursor: "pointer",
event: "orderByPrice()"
},
{
descriptor: "Link",
icon: "/assets/imgs/timer-32.png",
cursor: "default",
event: "null"
},
{
descriptor: "Datum",
icon: "/assets/imgs/timer-32.png",
cursor: "pointer",
event: "null"
}
];
The orderByPrice
-Method looks like this:
orderByPrice() {
this.isSortedAsc = !this.isSortedAsc;
const direction = this.isSortedAsc ? "desc" : "asc";
this.gearPieces = this.gearService.getGearComponentsOrderByPrice(direction);
}
I call it like this in the html
-File:
<table class="table table-dark">
<thead>
<tr>
<th *ngFor="let header of headerElements">
<img src={{header.icon}} width="32" height="32" style="cursor: {{header.cursor}};" (click)="{{header.event}}"/>{{header.descriptor}}
</th>
</tr>
</thead>
</table>
Unfortunately, setting a specific method to be called on (click)
gives me this error:
Template parse errors: Parser Error: Got interpolation ({{}}) where expression was expected at column 0 in [{{header.event}}]
Is it even possible, to accomplish this?
Upvotes: 0
Views: 1183
Reputation: 12960
Update
Instead of function names, you can directly attach the function references to the event prop in your object. So if you have a method:
orderByPrice() {
console.log("order by price called");
}
attach the references like:
headerElements = [
{
descriptor: "Price",
icon: "/assets/imgs/description-32.png",
cursor: "pointer",
event: this.orderByPrice //<---- assign the actual reference of the function
},
.
.
]
Old answer (I don't know what was I thinking)
You can create reference for the methods in your class. Something like:
orderByPrice = () => {
console.log("order by price called");
}
Use the function references for assigning to event
to header elements instead of their names
The create your object like:
headerElements = [
{
descriptor: "Name",
icon: "/assets/imgs/name-32.png",
cursor: "default",
event: null
},
{
descriptor: "Price",
icon: "/assets/imgs/description-32.png",
cursor: "pointer",
event: this.orderByPrice //<---- assign the actual reference of the function
},
{
descriptor: "Link",
icon: "/assets/imgs/timer-32.png",
cursor: "default",
event: null // <-- as described in comments have it falsy, actual null
},
{
descriptor: "Datum",
icon: "/assets/imgs/timer-32.png",
cursor: "pointer",
event: null
}
];
Have your HTML like:
<th *ngFor="let header of headerElements">
<img src={{header.icon}} width="32" height="32" style="cursor: {{header.cursor}};" (click)="header.event && header.event()"/>{{header.descriptor}}
</th>
Edit
(Based on the comments)
This part contains checks and explanations if it is correct to have a variable in an angular class referencing a function.
I checked the component instance when we add a variable as a function reference rather than adding a named function in the class.
So, When a named function is added it appears in the prototype of the component instance. But if I have a variable reference to the function then the variable(so the function) appears directly in the component instance(this means code duplication).
To avoid this, we can add the function to the prototype of the class.
AppComponent.prototype['orderByPrice'] = (): void => {
console.log("order by price called");
}
I couldn't find any other differences. I am open to suggestions, counter questions and correcting my mistake if this is not correct.
Thanks!
Upvotes: 0
Reputation: 1588
One of the easy solution will be (If headerElements
variable data is not retrieved from server and is locally defined):
Change headerElements.event as follows:
headerElements = [
{
descriptor: "Name",
icon: "/assets/imgs/name-32.png",
cursor: "default",
event: () => {return this.test1();}
},
{
descriptor: "Price",
icon: "/assets/imgs/description-32.png",
cursor: "pointer",
event: () => {return null;}
},
{
descriptor: "Link",
icon: "/assets/imgs/timer-32.png",
cursor: "default",
event: () => {return null;}
},
{
descriptor: "Datum",
icon: "/assets/imgs/timer-32.png",
cursor: "pointer",
event: () => {return this.test2('It works!');}
}
];
Also, modify HTML click event as follows:
(click)='value.event()'
Upvotes: 1