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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.