Search code examples
angularjsangularjs-directiveangularjs-scope

bind or print from directive


I am accessing my selected file using a directive as suggested by some SO answers,and i am able to console my file name in the directive.Now i want to bind that name to html from that directive.....how can i do that??

See the p tag after input

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
   <input type="file" myfilename />
  <P>{{files[0].name}}</p>
  </body>
<script>
  
  var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

});
app.directive('myfilename', [function () {
    return {
        link: function (scope, element, attrs) {
            element.on('change', function  (evt) {
               scope.files = evt.target.files;
                console.log(scope.files[0].name);
                
            });
        }
    };
}]);
  </script>
</html>


Solution

  • Just add scope.$apply() after scope.files = evt.target.files; in direcives.

    The reason why it does not show the updated value immediately is because the 2 way binding updates the parent (or the consumer scope of the directive) scope's bound value only during the digest cycle. Digest cycle happens after the ng-click is triggered. And hence $scope.files in the controller is not yet updated. You can get around this in many ways by using a timeout which will defer the action to run at the end of the digest cycle. You could also do it by setting an object which holds the value as 2-way bound property. Since 2-way bound property and parent scope share the same object reference you will see the change immediately.

    Here is the full code

        <!DOCTYPE html>
    <html ng-app="plunker">
    
      <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="[email protected]" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
        <script src="app.js"></script>
      </head>
    
      <body ng-controller="MainCtrl">
       <input type="file" myfilename />
      <P>{{files[0].name}}</p>
      </body>
    <script>
    
      var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {
    
    });
    app.directive('myfilename', [function () {
        return {
            link: function (scope, element, attrs) {
                element.on('change', function  (evt) {
                   scope.files = evt.target.files;
                   scope.$apply();
                    console.log(scope.files[0].name);
    
                });
            }
        };
    }]);
      </script>
    </html>