user2165994 user2165994 - 1 year ago 100
AngularJS Question

How do I dynamically define a function to call with ng-click in AngularJS directive template

I'm trying to dynamically generate form inputs and an associated action menu based on the model. I'm able to pass the field to be used and the menu, but I can't figure out how to configure ng-click to call the appropriate function defined in the model. See fiddle :


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

myApp.directive('myDirective', function($compile) {
return {
restrict: "E",
replace: true,
scope : {
field: '=',
label: '=',
menu: '='
link: function (scope, element, attrs) {
element.html('{{label}}: <input ng-model="field"> <ul ng-repeat="item in menu"<li><a ng-click="item.func">{{item.title}}</a></li></ul>');
//myApp.factory('myService', function() {});

function MyCtrl($scope) {
$scope.status = 'You have not picked yet';

$ = [
{ "title" : "Action 1", "func" : "ActionOne()"},
{ "title" : "Action 2", "func" : "ActionTwo()"},

$scope.fieldOne = "I am field 1";
$scope.fieldTwo = "I am field 2";

$scope.ActionOne = function() {
$sopce.status = "You picked Action 1";

$scope.ActionOne = function() {
$sopce.status = "You picked Action 2";


<div ng-app = "myApp">
<div ng-controller="MyCtrl">
<p><my-directive field="fieldOne" label="'Field 1'" menu="menu"></my-directive></p>
<p><my-directive field="fieldTwo" label="'Field 2'" menu="menu"></my-directive></p>
Hello, {{status}}!

Any help would be appreciated. I've tried the following ng-click approaches in the directive


What am I doing wrong? Or is there a better way to do this (the menu structure including the functions to be called have to come from the model in order for me to build a generic form generation capability).

Answer Source

Here's your fixed fiddle:

There were a great number of problems with it.

  1. You've got a typo $scope typo'd 4 times as $sopce.
  2. If you want items within $ to have access to ActionOne and ActionTwo, you'll need to define those Action functions above where you define $ (that's just how JavaScript works when you're assigning functions to variables).
  3. You've got ActionOne defined twice, where the second one should be ActionTwo.
  4. ng-click is expecting a method call, not a pointer to a function so it should be ng-click="item.func()".
  5. You want your menu items to have pointers to functions, but you've defined them as strings... even if you take "ActionOne()" out of quotations, it still won't work for two reasons:
    1. ActionOne doesn't exist as a funcion inside of MyCtrl, instead it needs to be referenced as $scope.ActionOne
    2. You just want a pointer to ActionOne, you don't actually want to call it at this point. Because of the parenthesis, both actions would be called when MyCtrl is initalized.

It would probably be a good idea to understand the basics of JavaScript before jumping into Angular, as Angular assumes you have a good understanding of the nuances of the language. There are a series of videos by Douglas Crockford that can get you started.