2

My question is very simple, I just want to pass a controller function to directive. In other terms, I just want to call a controller function from directive.

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

myapp.controller('myCtrl',['$scope','$timeout',function($scope,$timeout){
  
  $scope.fnItemsOnAdded = function(itms){
     alert('Hi, I am in controller add. Here are your Items: '+JSON.stringify(itms));
    }
    $scope.fnItemsOnCancel = function(itms){
     alert('Hi, I am in controller cancel. Here are your Items: '+JSON.stringify(itms));
    }
  
  }]);

myapp.directive('myPicker',['$timeout',function($timeout){
  
  
  var dtv={};
  
  dtv.template = '<li ng-repeat="itm in ngModel.ItemsList"><label><input type="checkbox" ng-model="itm.IsSelected" />{{itm.Name}}</label></li>';    
  dtv.template += '<a href="javascript:void(0)" ng-click="addItems()" class="addItems">add items</a>';
  dtv.template += '<a href="javascript:void(0)" ng-click="cancelItems()" class="cancel">cancel</a>';
  
  dtv.scope =  { postUrl: '@', jsonadd: '&', jsoncancel: '&' };
  
  dtv.restrict = 'A';
  
dtv.link = function($scope,elm,attrs){
  
  $scope.ngModel={};
  $scope.ngModel.SelectedKeys=[];
  
  $timeout(function(){
    $scope.ngModel.ItemsList = [
    {Name:"Item1",IsSelected:false},
      {Name:"Item2",IsSelected:false},
      {Name:"Item3",IsSelected:false},
      {Name:"Item4",IsSelected:true},
      {Name:"Item4",IsSelected:false},
    ];
    
    },100);
  
    $scope.addItems = function(){
      
      //Dummy logic to update SelectedKeys
      for(var idx =0;idx<$scope.ngModel.ItemsList.length;idx++){
      if($scope.ngModel.ItemsList[idx].IsSelected){
      $scope.ngModel.SelectedKeys.push($scope.ngModel.ItemsList[idx]);
      }
      }
      
    alert("i'm in directive add. Lemme call parent controller");
    $scope.jsonadd($scope.ngModel.SelectedKeys);
    }
  
    $scope.cancelItems = function(){
    alert("i'm in directive cancel. Lemme call parent controller");
    $scope.jsonadd($scope.ngModel.SelectedKeys);
    }
    
  }
  
  
  return(dtv);
  
  
  }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myapp" ng-controller="myCtrl">

<div class="jqmWindow" id="myPickListDiv" my-picker  jsonadd="fnItemsOnAdded" jsoncancel="fnItemsOnCancel" post-url="/myurl"></div>
  
  </div>
  • I have tried this approach but it doesn't trigger the function, doesn't throw any error either.
  • I tried this and this approach - it returns an error $apply is already in progress.

Can anybody please help me where I'm going wrong here. I believe it has got something to do with $scope inheritance or convention.

I know I am doing some petty mistake here, just that I am can't figure it in the rush I am.

Thank you very much for you help!

Community
  • 1
  • 1
amitthk
  • 1,115
  • 1
  • 11
  • 19

1 Answers1

5

You're almost there. The syntax for passing params is a little strange.

In your HTML, use something like

<div my-picker jsonadd="fnItemsOnAdded(items)"...

and in your directive...

$scope.jsonadd({items: $scope.ngModel.SelectedKeys})

The keys in the object passed to the isolate scope function (jsonadd, jsoncancel) need to match the argument names used in the attribute.

I don't know where SelectedKeys comes from but I assume you've just omitted something for brevity.

Phil
  • 157,677
  • 23
  • 242
  • 245
  • Yes you're right, I'm sorry I missed the SelectedKeys part. Thank you very much for your insightful reply. Lemme try this right now. – amitthk Feb 23 '15 at 03:29
  • I actually tried your suggestion and it works fine [here](http://jsfiddle.net/amitthk/y68zhoLu/). But the same thing doesn't work in my app. Only difference I have in my app is I have like 3 controllers inside same ng-app on my page. My directive is inside my original controller "myCtrl" in above case. There seem to be some other crazy bug in my code I don't seem to understand. Anyway thank you very much for your help. – amitthk Feb 23 '15 at 04:42