Angular directive does not call parent scope function

580 Views Asked by At

I am trying to call a parent function from a directive. But my functions are not being called.

Here is the code for your reference.

Controller

'use strict';

angular.module('myApp')
  .controller('MyCtrl', function($scope) {
    $scope.iconSelected = function() {
      console.log('iconSelected');

      var icon = angular.element('#icon').prop('files');

      if (!icon) {
        return;
      }

      icon = icon[0];

      var _URL = window.URL || window.webkitURL;
      $scope.utility.icon = _URL.createObjectURL(icon);
    }

    $scope.sourceSelected = function() {
      console.log('sourceSelected');

      var source = angular.element('#source');
      console.log(source.prop('files'));
    };
  });

Directive

'use strict';

angular.module('myApp')
  .directive('uploadButton', function() {
    return {
      templateUrl: 'app/directives/upload-button/upload-button.html',
      restrict: 'E',
      transclude: true,
      scope: {
        onSelect: '&'
      },
      link: function(scope, element, attrs) {
        scope.name = attrs.name;
        scope.id = attrs.id || attrs.name;
        scope.label = attrs.label || attrs.name;
        scope.accept = attrs.accept;

        scope.showDialog = function() {
          element.find('#' + scope.id).trigger('click');
        };

        element.find('input').change(function() {
          scope.$apply(attrs.onSelect);
        });
      }
    };
  });

Directive Template

<md-input-container class="upload-button">
  <md-button class="md-raised" ng-click="showDialog()">
    <span ng-transclude></span>
  </md-button>
  <input type="file" name="{{name}}" id="{{id}}" aria-label="{{label}}" accept="{{accept}}">
</md-input-container>

Directive Usage

<upload-button name="icon" on-select="iconSelected()" accept=".svg">Choose an icon</upload-button>
<upload-button class="source-btn" name="source" on-select="sourceSelected()" accept=".zip">Select source code</upload-button>
1

There are 1 best solutions below

0
On BEST ANSWER

Inside your directive code you are calling onSelect using attrs.onSelect change it to scope.onSelect. attrs.onSelect will just give you the string value iconSelected(). You need the function reference which will be available in the isolated scope which is created by the directive.

element.find('input').change(function() {
  scope.$apply(scope.onSelect);
});