ManxJason ManxJason - 1 year ago 111
AngularJS Question

Apply ng-change to an <input type="file"..>, that already uses it's own Directive

I want to call a validateFormat() function each time an input of type 'file' changes. Note that a custom directive is used 'file-model'

If I try to add 'ng-change="validateFormat()"' to the input, the console prints the following error: no controller: ngModel.

How can I bind this element to ng-change?


<div ng-controller="MyControllerController">
<input type="file" file-model="file" />
<button ng-click="uploadFile()">Upload</button>

Angular 1.x:

var module = angular.module("umbraco");

module.controller('OnlineServices.JobCentreUploadController', [
'$scope', 'fileUpload', function($scope,
$scope.uploadFile = function () {
var file = $scope.file;
var uploadUrl = "/umbraco/api/jc/Upload";
fileUpload.uploadFileToUrl(file, uploadUrl, $scope);

module.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;

element.bind('change', function () {
scope.$apply(function () {
modelSetter(scope, element[0].files[0]);

module.service('fileUpload', ['$http', 'notificationsService', function ($http, notificationsService) {
this.uploadFileToUrl = function (file, uploadUrl) {
var fd = new FormData();
fd.append('file', file);
$, fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
.success(function () {
notificationsService.success("Success", "File uploaded successfully.");
.error(function () {
notificationsService.error("Error", "File has not been uploaded.");

Answer Source

ng-change directive needs ng-model Behind the screen ng-change sets a watch for the corresponding ng-model.

Coming to your problem you are trying to call ng-change without specifying ng-model on it that is the reason for error.

In your custom directive you've created an event handler for change event.

So if you want to set up ng-change event for your input element you can do it in your custom directive only no need to go for ng-change directive.

In order to do so you need to pass your validateFormat function as paramter to custom directive and execute the function in change callback like below:

Example code:

element.bind('change', function () {
    scope.$apply(function () {
        modelSetter(scope, element[0].files[0]);
    //Get this function using isolated scope and call it
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download