2

I am not able to pass data to controller's function through angular directive, directive has one change event. In which i want to pass my dynamic id. In controller i have myArray

$scope.myArray = [1,2,3,4,5];

I have following html.

<div ng-repeat="data in myArray track by $index">
    <input type="file" ng-upload-change="uploadFile($event, $id)" my-id="$index">
<div>

In Controller:

$scope.uploadFile = function($event, $id){
    var files = $event.target.files;
    console.log("id:"+$id);
};

In directive:

app.directive('ngUploadChange', function() {
    return{
        scope:{
            ngUploadChange:"&",
            myId:"="
        },
        link:function($scope, $element, $attrs){
            $element.on("change",function(event){
                $scope.ngUploadChange({$event: event, $id : $scope.myId});
            })
            $scope.$on("$destroy",function(){
                $element.off();
            });
        }
    }
});

As you can see that when i pass uploadFile function to ngUploadChange directive, it always pass first id (in this case it is 1) to controllers function. I am not getting updated id every time.

Thanks in advance.

1
  • 2
    I tried your problem in fiddle, and I get the updated Ids always. Try this, check what is missing apart from your problem ? Commented Apr 1, 2017 at 10:41

2 Answers 2

1

When you want to pass parameters through the function, you can use "=" instead of "&" for that attr binding, and in your HTML, you can specify like this:

<input type="file" ng-upload-change="uploadFile" ... />

And, I changed the way you were passing an object of params since there is no need to create that object.

Now, if you see the code snippet below, it correctly logs id: x (0-based) on each file upload.

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

//myApp.directive('myDirective', function() {});
myApp.controller('MyCtrl', function MyCtrl($scope) {
  $scope.myArray = [1, 2, 3, 4, 5];
  $scope.uploadFile = function($event, $id) {
    var files = $event.target.files;
    console.log("id: " + $id);
  };
});

myApp.directive('ngUploadChange', function() {
  return {
    scope: {
      ngUploadChange: "=",
      myId: "="
    },
    link: function($scope, $element, $attrs) {
      $element.on("change", function(event) {
        $scope.ngUploadChange(event, $scope.myId);
      })
      $scope.$on("$destroy", function() {
        $element.off();
      });
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
  <div ng-repeat="data in myArray">
    <input type="file" ng-upload-change="uploadFile" my-id="$index">
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

1

It is better to write the directive without isolate scope.

app.directive('ngUploadChange', function() {
    return{
        /*
        scope:{
            ngUploadChange:"&",
            myId:"="
        },*/
        link:function($scope, $element, $attrs){
            $element.on("change",function(event){
                var locals = { $event: event,
                               $id : $scope.$eval($attrs.myId)
                }; 
                $scope.$eval($attrs.ngUploadChange, locals);
            });
            /*
            $scope.$on("$destroy",function(){
                $element.off();
            });*/
        }
    }
});

Use $scope.$eval instead of isolate scope bindings.

Isolate scope adds a scope and additional watchers which have been known to cause digest cycle delays that fight the ngModelController.

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.