javascripthtmlangularjsangularjs-directive

Angular directive modifies scope, but not after setTimeout


// javascript

var a = angular.module('minimalReproApp', [

    ])
a.controller('MainCtrl', function($scope) {
        $scope.fileData = {}
        $scope.fileData.xmlData = "ControllerScope";
    }).directive('dropzone', function() {
    return {
        restrict: 'AE',
        scope: '=',
        transclude: true,
        link: function(scope, elem) {
            console.log(scope)
            console.log(scope.fileData.xmlData)
            scope.fileData.xmlData = "directive";
            setTimeout(function() {
                console.log(1000)
                scope.fileData.xmlData = "something";
            }, 1000)
        }
    };
});

//html

<div ng-app="minimalReproApp">
<div ng-controller="MainCtrl">
{{a}}
    <div class="jumbotron" dropzone>
   </div>
     <div>{{fileData.xmlData}} </div>
</div>

I'm trying to implement a custom dropzone directive that incorporates the html5 Filereader API. The filereader is intended to modify scope outside of the dropzone directive.

As you can see from this fiddle: http://jsfiddle.net/HB7LU/7514/. The code initally binds the directive scope to the html, but doesn't after the timeout (my minimal reproduction of the file drop action) - why is this? How would I fix this?


Solution

  • You should use $timeout instead of setTimeout.
    Of course, you need to inject it in your controller/service.

    The benefit (in that case) is that $timeout involves a digest, in order to synchronize the scope's values.

    Otherwise, you would manually call apply like this (but not recommended) :

    setTimeout(function() {
                    scope.$apply(function(){
                      scope.fileData.xmlData = "something";
                   };
                }, 1000);