Problem with angular ng-repeat directive

2

I have a problem with Angular's ng-repeat directive, I'm creating a banner component that works as follows: when you click on add image, that image is converted to base64 and the new image is added to an array and it is with this array that the path of the ng-repeat is made, the code that I have is the following:

<div class="img" ng-repeat="imagen in imagenes track by $index">
    <div class="cont_img">
        <img src="{{ imagen.imagen }}" alt="" class="img-responsive imagen">
    </div>
</div>

and on the Controller:

$scope.imagenes = [];
$scope.cambioUpload = function($file){
    var reader  = new FileReader();

    reader.readAsDataURL($file.value[0]);

    var dataURL = '';

    reader.onload = function(){
        dataURL = reader.result;  

        $scope.imagenes.push({
            temporal : $scope.imagenes.length + 1,
            imagen: dataURL,
            tiempo: 0
        });
    }                
}

The problem is that the new image that was added is not updated in real time, it appears only when clicking anywhere on the page, I do not know why this is happening.

    
asked by Bender 05.09.2017 в 18:43
source

1 answer

4

It is because adding the element outside the cycle $digest of angular.

When the function $scope.cambioUpload is executed, any model that is updated between the start and end of the function will be updated in the view. Now, the event FileReader#onload breaks that rule and its execution begins when the image loads, which means that the execution of the method $scope.cambioUpload has finished. In other words: its execution is asynchronous. And since the $ digest is finished, the changes in the view will not be updated until another $digest is executed.

This is what happens in your case:

se ejecuta funcion $scope.cambioUpload
  se activa el $digest
   se inicializa instancia FileReader()
    se agrega evento onload a instancia FileReader()
     termina ejecucion metodo $scope.cambioUpload
      termina $digest y actuliza la vista
   ..
   ..
   se ejecuta el metodo onload()
    agrega elemento a la coleccion
     finaliza ejecucion onload()

Notice that in the case of onload, $ digest is not executed to update the view. so you have to force the $digest with $apply() to update the view once the method onload is executed:

reader.onload = function(){ 

    // forzamos a que angular actualize la vista manualmente.
    $scope.$apply(function(){ 
         $scope.imagenes.push({
            temporal : $scope.imagenes.length + 1,
            imagen: dataURL,
            tiempo: 0
         });
   });

}  
    
answered by 05.09.2017 / 19:10
source