简体   繁体   中英

angular not updating $scope variable in controller

I have a directive to upload a file to the browser

angular.module('angularPrototypeApp')
.directive('upload', ['$parse', function ($parse) {
return {
    restrict: 'A',
    scope: false,
    link: function(scope, ele, attrs) {

        var fn = $parse(attrs.upload);
        ele.on('change', function(onChangeEvent){
            var reader = new FileReader();

            reader.onload = function(onLoadEvent) {
                scope.$apply(function(){
                    fn(scope, {$fileContents: onLoadEvent.target.result} );
                });
            }

            reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
        })

    }
  };
}]);

The code is taken from here: https://veamospues.wordpress.com/2014/01/27/reading-files-with-angularjs/

The view looks like this:

<progressbar class="progress-striped active" value="dynamic" </progressbar>
<input type="file" upload="parseInputFile($fileContents)">

In the controller I do the following:

angular.module('angularPrototypeApp')
.controller('Gc2xlsxCtrl', ['$scope', 'blockUI', function ($scope,  $timeout, blockUI) {

$scope.dynamic = 0;

$scope.parseInputFile = function($fileContents){
    $scope.$broadcast('fileUploaded', $fileContents);
}

$scope.$on('fileUploaded', function(event, fileContents) {
    if(fileContents !== undefined){
        blockUI.start();

        //a lot of work is done herem takes between 2 and 20 Seconds
        for(var i = 1; i <= 100; i++){
            $scope.dynamic += 1;
        }

        blockUI.stop();
    }
});
}]);

My problem is that the update to $scope.dynamic is shown in the view only after the whole method has finished. The same is true for blockUI. The logs say that it's called right at the beginning of the method, but the view is never upated. Any help on this would be fantastic!

This part:

//a lot of work is done here, takes between 2 and 20 Seconds
for(var i = 1; i <= 100; i++){
    $scope.dynamic += 1;
}

Is synchronous code and won't update the view until it's done. Basically, the loop updates $scope.dynamic from 1 to 100, but the view can't change until it's done with that; so you just see it at 1, then at 100.

You need to have the work done asynchronously to allow the view to be updated while the work is happening.

How best to go about doing that is another question. You could use $q in AngularJS to do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM