how to use a model property as variable ng-click

2019-05-01 13:58发布

问题:

I'd like to have function calls for ng-click stored as strings in my model. I can't use ng-click="m.func", and if i'm using ng-click="{{m.func}}" ist also not working.

http://jsfiddle.net/j8wW5/19/

It also looks like angular 1.2.0 throws an error in case of ng-click="{{m.func}}".

How can I bring it to work?

<div ng-app="myApp" ng-controller="myCtrl">
    <div ng-repeat="m in model"><a href="#" ng-click="{{m.func}}">{{m.caption}}</a></div>
</div>

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope) {
    $scope.model = [
        {
            caption: 'callme a',
            func : 'callme_a()'
        },
        {
            caption: 'callme b',
            func : 'callme_b()'
        }
    ]

    $scope.callme_a = function() {
        alert("called a");
    }

    $scope.callme_b = function() {
        alert("called b");
    }
});

回答1:

It could be that ng-click is attaching an event listener to the dom with the ng-click attribute before it's evaluated to a string.

So, I've overridden the ngclick with a timeout to make what you want work :)

var app = angular.module('myApp', []); 
app.directive('ngClick', ['$timeout','$parse', function($timeout, $parse) {
          return {
              compile: function($element, attr) {
                  return function(scope, element, attr) {
                      //I've wrapped this link function code in a $timeout
                      $timeout(function() {
                          var fn = $parse(attr["ngClick"]);
                          $(element[0]).on("click", function(event) {
                              scope.$apply(function() {
                                  fn(scope, {$event:event});
                              });
                          });
                      })
                  };
              }
          };
      }]);

(Here is the source code for ngClick - https://github.com/angular/angular.js/blob/master/src/ng/directive/ngEventDirs.js)

Check the fiddle here with the demo - http://jsfiddle.net/R2Cc9/5/



回答2:

You can do something like this:

In your html:

<div ng-repeat="m in model"><a href="#" ng-click="call(m)">{{m.caption}}</a></div>

In your controller:

$scope.callme_a = function() {
    alert("called a");
}

$scope.callme_b = function() {
    alert("called b");
}

$scope.model = [
    {
        caption: 'callme a',
        func : $scope.callme_a
    },
    {
        caption: 'callme b',
        func : $scope.callme_b
    }
]

$scope.call = function(el) {
    el.func();   
}

Fiddle



回答3:

You can use

window["functionName"](arguments) //if the functioName is defined in global (window's scope)

OR

$scope["functionName"](arguments) //if the functioName is defined for $scope 

So, updated controller code (of Beterraba) would be

callme_a = function() {
    alert("called a");
}

callme_b = function() {
    alert("called b");
}

$scope.model = [
    {
        caption: 'callme a',
        func : "callme_a"
    },
    {
        caption: 'callme b',
        func : "callme_b"
    }
]

$scope.call = function(el) {
   window[el.func](arguments)
}


回答4:

This is a variation on @Beterraba's answer.

Here is the fiddle.

HTML:

<div ng-app="myApp" ng-controller="myCtrl">
    <div ng-repeat="m in model"><a href="#" ng-click="call(m.func)">{{m.caption}}</a></div>
</div>

JS:

$scope.call = function(func) {
    $scope[func]();
}

If you have to use strings to define the functions then this will work. But I would urge you to look again at your design.

Also, in order for this to work, you must take out the () in the function string:

$scope.model = [
    {
        caption: 'callme a',
        func : 'callme_a'
    },
    {
        caption: 'callme b',
        func : 'callme_b'
    }
]