Tony Hensler
Tony Hensler

Reputation: 1492

Dynamic (click) function - Angular2

I am having a little trouble with binding a dynamic function to a click event. Please see below:-

File 1

<title-bar [actions]='[{title: "Create A New Plan", link: "hello"}]' ></title-bar>

File 2

<div class="actions" *ngIf="actions">
    <a *ngFor="let action of actions" class="ui primary button" (click)="[action.link]()">{{action.title}}</a>
</div>

All of the code is working perfectly apart from when I am binding the action.link in the (click).

If I create the following button:-

<button (click)="hello()"></button>

It calls the hello() function as it should. but for some reason I am not able to get this to work dynamically.

Does anybody have a simple solution to this I may have over looked?

The function is calling a simple alert just for testing:-

public hello() {
    alert('test');
}

II have attempted to change the click event to the following but with no joy:-

(click)="action.link"
(click)="[action.link]()"
(click)="this[action.link]()"

I get the following errors respectively:-

No error, but not function called
inline template:3:2 caused by: ["hello"] is not a function
inline template:3:2 caused by: self.parentView.parentView.context[self.context.$implicit.link] is not a function

Any help with a push in the right direction will be very much appreciated.

Upvotes: 6

Views: 14002

Answers (4)

gr99t
gr99t

Reputation: 1

Component.ts

items = [
  {
    name: 'share',
    action: this.share
  },
  {
    name: 'report',
    action: this.report
  }
];

share() {}
report() {}

Component.html

<el *ngFor="let i of items" (click)="i.action()"></el>

Upvotes: 0

Chris Newman
Chris Newman

Reputation: 3312

I needed to do something similar with ngFor. Accepted answer works but gave me a linting error: 'Call target is not callable'

There's another SO answer from Günter which helped me find a lint-error free solution : Angular2 passing function as component input is not working

My component.ts

this.myLinks = [
  {
    imgSrc: 'assets/a.png,
    clickFunction: this.aFn,
  },
  {
    imgSrc: 'assets/b.png,
    clickFunction: this.bFn,
  },
];


aFn() {
  console.log('function A');
}
bFn() {
  console.log('function B');
}

My template.html

<div *ngFor="let link of myLinks">
   <img
     [src]="link.imgSrc"
     (click)="link.clickFunction.apply(this)"
   />
</div>

Upvotes: 4

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657158

In the component you need

get self() { return this; }

and in the template

<a *ngFor="let action of actions" class="ui primary button"
  (click)="self[action.link]()">{{action.title}}</a>

Use

<a *ngFor="let action of actions" class="ui primary button"
  (click)="this[action.link]()">{{action.title}}</a>

Upvotes: 13

Leen Blom
Leen Blom

Reputation: 1

It worked for me like this:

(click)=self[action.link]()

Upvotes: 0

Related Questions