1

I am building a dropdown menu directive which allows you to optionally attach a function to each item in the list. I know how to pass one function per attribute into the directive, but I'm hoping that there is a way to pass multiple functions.

<dropdown items="['item1', 'item2']" actions="['action1()', 'action2()']"></dropdown>

or better yet:

<dropdown items="[{'item1':action1()}, {'item2':action2()}]"></dropdown>

which could be used to generate:

<dropdown items="['item1', 'item2']" actions="['action1()', 'action2()']">
    <a ng-click="action1()">item1</a>
    <a ng-click="action2()">item2</a>
</dropdown>
2
  • Why not action1="action1()" action2="action2(). You probably won't have too much functions and map them with the & on the directive. Otherwise, passing the array (with =) will force you to iterate over the array in order to parse the functions. Commented Oct 5, 2014 at 1:15
  • It seems cleaner to pass one object in. How would I access the functions through =? It just ends up treating the whole thing as a string and I can't access the actual functions. Commented Oct 5, 2014 at 1:25

2 Answers 2

2

You can use the = object notation for your scope in accepting an array of objects with properties that you can assign to your directive.

DEMO

Controller

  .controller('Ctrl', function($scope) {

    var action = function() {
      window.alert(this.label);
    };

    $scope.items = [{
      label: 'Item 1',
      action: action
    }, {
      label: 'Item 2',
      action: action
    }, {
      label: 'Item 3',
      action: action
    }, {
      label: 'Item 4',
      action: action
    }];
  })

Directive

  .directive('dropdown', function() {
    return {
      restrict: 'E',
      scope: {
        items: '='
      },
      template: 
        '<div ng-repeat="item in items track by $index" ng-click="item.action()">' + 
          '<a ng-bind="item.label"></a>' +
        '</div>'
    };
  });

index.html

  <body ng-controller="Ctrl">
    <dropdown items="items"></dropdown>
  </body>
Sign up to request clarification or add additional context in comments.

5 Comments

what if action takes arguments?
Check this forked plunker :)
thanks but I mean in action property: $scope.items = [{ label: 'Item 1', action: action(arg) },
What is your use case? if this is going to be another problem that is perhaps entirely different from the use case represented by this problem, then I suggest you ask another question :)
I just want to pass parameters to action function: var action = function(parameter) { alert(parameter); };
0

to pass any form of function to a directive that does same thing in thesense ike a call back from the directive to execute the function , the method should be as below

  1. First of all use the return scope to contain the functionName : '&' as it is used in passing functions
  2. Then returning it back should look like this from ur template ng-click='functionName({params:values[,params2:value2]})'

as the above would send the param as argument to the calling controller calling the directive

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

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  
  $scope.items=['value1','value2','value3'];
  $scope.items2=['value12','value22','value32'];
  
  $scope.clicked='';
  
  $scope.alert=function(val){
    $scope.clicked=val;
  }
  
   $scope.alerti=function(val){
  $scope.clicked=val+"-Second";
  }
  
});

app.directive('direct', function(){
  return {
        restrict: 'E',
        scope : {
          actionTest:'&',
          tests:'='
        },
       // controller: 'ctrl',
        template: '<ul><li ng-repeat="test in tests" ng-click="actionTest({val:test})">{{test}} </li></ul>'
  }
});
/*
app.controller('ctrl', function($scope){
  
});*/
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="testApp">
<div  ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>
    <p>CLicked : {{clicked}}</p>
    
    <direct tests='items' action-test='alert(val)'></direct>
  
    <!--with a different action function-->
     <direct tests='items2' action-test='alerti(val)'></direct>
 
  </div>
</div>

Comments

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.