AngularJs: How to check for changes in file input fields?

前端 未结 15 1153
傲寒
傲寒 2020-11-22 09:06

I am new to angular. I am trying to read the uploaded file path from HTML \'file\' field whenever a \'change\' happens on this field. If i use \'onChange\' it works but when

相关标签:
15条回答
  • 2020-11-22 09:47

    Working Demo of "files-input" Directive that Works with ng-change1

    To make an <input type=file> element work the ng-change directive, it needs a custom directive that works with the ng-model directive.

    <input type="file" files-input ng-model="fileList" 
           ng-change="onInputChange()" multiple />
    

    The DEMO

    angular.module("app",[])
    .directive("filesInput", function() {
      return {
        require: "ngModel",
        link: function postLink(scope,elem,attrs,ngModel) {
          elem.on("change", function(e) {
            var files = elem[0].files;
            ngModel.$setViewValue(files);
          })
        }
      }
    })
    
    .controller("ctrl", function($scope) {
         $scope.onInputChange = function() {
             console.log("input change");
         };
    })
    <script src="//unpkg.com/angular/angular.js"></script>
      <body ng-app="app" ng-controller="ctrl">
        <h1>AngularJS Input `type=file` Demo</h1>
        
        <input type="file" files-input ng-model="fileList" 
               ng-change="onInputChange()" multiple />
        
        <h2>Files</h2>
        <div ng-repeat="file in fileList">
          {{file.name}}
        </div>
      </body>

    0 讨论(0)
  • 2020-11-22 09:48

    Similar to some of the other good answers here, I wrote a directive to solve this problem, but this implementation more closely mirrors the angular way of attaching events.

    You can use the directive like this:

    HTML

    <input type="file" file-change="yourHandler($event, files)" />
    

    As you can see, you can inject the files selected into your event handler, as you would inject an $event object into any ng event handler.

    Javascript

    angular
      .module('yourModule')
      .directive('fileChange', ['$parse', function($parse) {
    
        return {
          require: 'ngModel',
          restrict: 'A',
          link: function ($scope, element, attrs, ngModel) {
    
            // Get the function provided in the file-change attribute.
            // Note the attribute has become an angular expression,
            // which is what we are parsing. The provided handler is 
            // wrapped up in an outer function (attrHandler) - we'll 
            // call the provided event handler inside the handler()
            // function below.
            var attrHandler = $parse(attrs['fileChange']);
    
            // This is a wrapper handler which will be attached to the
            // HTML change event.
            var handler = function (e) {
    
              $scope.$apply(function () {
    
                // Execute the provided handler in the directive's scope.
                // The files variable will be available for consumption
                // by the event handler.
                attrHandler($scope, { $event: e, files: e.target.files });
              });
            };
    
            // Attach the handler to the HTML change event 
            element[0].addEventListener('change', handler, false);
          }
        };
      }]);
    
    0 讨论(0)
  • 2020-11-22 09:51

    Angular elements (such as the root element of a directive) are jQuery [Lite] objects. This means we can register the event listener like so:

    link($scope, $el) {
        const fileInputSelector = '.my-file-input'
    
        function setFile() {
            // access file via $el.find(fileInputSelector).get(0).files[0]
        }
    
        $el.on('change', fileInputSelector, setFile)
    }
    

    This is jQuery event delegation. Here, the listener is attached to the root element of the directive. When the event is triggered, it will bubble up to the registered element and jQuery will determine if the event originated on an inner element matching the defined selector. If it does, the handler will fire.

    Benefits of this method are:

    • the handler is bound to the $element which will be automatically cleaned up when the directive scope is destroyed.
    • no code in the template
    • will work even if the target delegate (input) has not yet been rendered when you register the event handler (such as when using ng-if or ng-switch)

    http://api.jquery.com/on/

    0 讨论(0)
提交回复
热议问题