0

Assuming I have the following:

<button ng-repeat="{{item in items}}" ng-click="{{item.name}}Function()">{{item.name}}</button>

I need to be able to get the ng-click to dynamically change based on the item.name such as

firstItemFunction()
secondItemFunction()

etc.

2 Answers 2

1

If $scope has references to the functions:

$scope.items = 
[
  { name: 'firstItemFunction' },
  { name: 'secondItemFunction' }
];

$scope.firstItemFunction = function () {
  console.log('firstItemFunction');
};

$scope.secondItemFunction = function () {
  console.log('secondItemFunction');
};

HTML:

<button ng-repeat="item in items" ng-click="this[item.name]()">
  {{item.name}}
</button>

Demo: http://plnkr.co/edit/FSrGumlZqm4Rdku6I3X5?p=preview

Alternatively:

$scope.items = [{
  name: 'firstItemFunction'
}, {
  name: 'secondItemFunction'
}];

$scope.firstItemFunction = function() {
  console.log('firstItemFunction');
}

$scope.secondItemFunction = function() {
  console.log('secondItemFunction');
}

$scope.execute = function(action) {
  $scope[action]();
};

And:

<button ng-repeat="item in items" ng-click="execute(item.name)">
  {{item.name}}
</button>

Demo: http://plnkr.co/edit/6jATpgEAvFgTFXbvQ6IE?p=preview

If the functions are defined globally use HTML from above, inject $window and:

$scope.items = [{
  name: 'firstItemFunction'
}, {
  name: 'secondItemFunction'
}];

$scope.execute = function(action) {
  $window[action]();
};

Demo: http://plnkr.co/edit/TinMbmvMTIQS4vptQMYf?p=preview

Sign up to request clarification or add additional context in comments.

3 Comments

Both answers are correct! tasesKATT answer is very elaborated and gives various alternatives, but I ended up using Mattew Beng method (using a switch instead of an if.. but the same overall idea).
BTW.. yours is the "more" correct, because you addressed the merging of the name into a dynamic function name with this "this[item.name]()"
I am building a screen where you select multiple social networks to authenticate, each obviously have a similar but different authentication process, so instead of having 10 different functions in the html, i just have one socialLogin(networkname) and then let the backend decide what to do.. I think it was more elegant that way instead of doing facebookLogin(), twitterLogin() directly in the frontend..
1

I would move the logic for determining which function to call to your javascript.

html

<button ng-repeat="{{item in items}}" ng-click="figureOutFunction(item)">{{item.name}}</button>

javascript

$scope.figureOutFunction(item){
    if(item.name == "firstItem"){
        firstItemFunction();
    }
    else if(item.name == "secondItem"){
        secondItemFunction();
    }
};

edit

If you want to avoid the switch, you can do it this way:

html

<button ng-repeat="{{item in items}}" ng-click="item.action()">{{item.name}}</button>

javascript

var firstItemFunction = function(){
    ...
};
var secondItemFunction = function(){
    ...
};

$scope.items = [{
  name: 'firstItem',
  action: firstItemFunction
}, {
  name: 'secondItem',
  action: secondItemFunction
}];

I would avoid creating unnecessary functions that call others.

1 Comment

I ended up implementing this, but with a switch. My main question was more about the actual usage of "item" instead of {{item}} in the click function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.