AngularJS - using data binding {{}} in ng-click
Asked Answered
K

2

7

Is there a way to change the method called by ng-click dynamically?

Something like this:

ng-click = "{{functionCalled}}"

and then declaring the function by:

$scope.functionCalled = "callThisFunction(param)";
Kinescope answered 28/4, 2014 at 19:31 Comment(0)
G
8

From the docs, ngClick just evaluates the expression in the context of the scope. There's nothing stopping you from referencing a function dynamically, but I'm not sure this is the intended method. I would probably call a function explicitly and switch the behavior based on a parameter instead like ng-click='myFunction(myParams)'. Nonetheless, here's an example of what you what to accomplish. http://jsfiddle.net/8cvGt/2/

HTML

<div ng-app='foo' ng-controller='ctrl'>
    <div ng-click='this[myVar]()'>{{ bar }}</div>
</div>

JavaScript

var app = angular.module('foo',[]).controller('ctrl',function($scope) {
    $scope.myVar = 'callIt';
    $scope.bar = 'before';
    $scope.callIt = function() {
        $scope.bar = 'after';
    }
});
Giaimo answered 28/4, 2014 at 19:41 Comment(11)
Great it works thanks, however is there a way I can dynamically set a parameter too? say for a function callit(callId) ?Kinescope
Sure, just add your paramater to your call. this[myFunc](myParam)Giaimo
I mean so that the parameter takes the value of an ng-model element form the view, such as <input id="inputAns" type="text" data-ng-model="quiz.ans1"></input>Kinescope
doing it the way you mentioned inputs a parameter value "quiz.ans1" rather than its actual valueKinescope
Do you have a functioning example of this? Unless you're calling it with this[myFunc]('quiz.ans1') it shouldn't be using the variable name.Giaimo
I updated the fiddle with the scenario I think you're talking about. jsfiddle.net/8cvGt/5Giaimo
I need to set the parameter in the controller so I am doing $scope.myParam = 'quizAns1'; I don't know how else to do itKinescope
Oh I see. You'll have to reference quizAns1 some other way then. I assume you're doing this in some sort of loop which is why you're doing it dynamically in the first place?Giaimo
Oh ok. No the button clicked is a 'done' button on the right side of the navigation bar (as there are in apps) and it is on the index page, outside of the ng-view. I want the button to be changed depending on which view I am in, therefore I am using $rootScope to change the button value from each individual controllerKinescope
probably a very bad way of doing itKinescope
Hmm, yeah I probably wouldn't use this to accomplish that use case. Either a dynamically determined partial for each view ng-include='myViewVariable + "button_section.html"', expand the view to include that section, or have a consistent API between views that it can call like ng-click='done()' and the done function determine what parameters it needs. Hard to tell which is appropriate without knowing more about the app.Giaimo
A
3

Assuming you have a set list of possible functions, use a central function to dispatch calls to other functions.

ng-click="dispatchFunction(param)"

Then

$scope.functionToCall = 'callThisFunction';

$scope.dispatchFunction = function(param) {
    switch($scope.functionToCall) {
         case (callThisFunction): callThisFunction(param);
    };

Edit: Actually, use a full dispatch table for this:

http://designpepper.com/blog/drips/using-dispatch-tables-to-avoid-conditionals-in-javascript

Aerobiosis answered 28/4, 2014 at 19:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.