Problem with Angular BlockUI - (AngularJS - Javascript)

0

I have the following problem, I need to block the UI when I upload a file and it is being processed, for this I use Angular BlockUI , but the problem is that the screen is blocked once the process is finished and not during it.

var processData = angular.module('library.process_data', ['blockUI']);

processData.controller('ProcessHomescope$scope', function HomeController($scope, blockUI, blockUIConfig) {
  var elementsTeradata = [];
  $scope.updloadTeradata = function(e) {

    //Bloqueo de UI
    blockUIConfig.delay = 100;
    blockUI.start("Cargando...");

    $timeout(function() {

      var files = e.target.files,
        f = files[0];

      var reader = new FileReader();

      reader.onload = function(e) {

        var data = e.target.result;

        if (!rABS) {
          data = new Uint8Array(data);
        }

        workbook = XLSX.read(data, {
          type: rABS ? 'binary' : 'array'
        });

        elementsTeradata = saveValues(workbook);

        alert("Ingrese segundo Archivo");

      };

      if (rABS) {
        reader.readAsBinaryString(f);
      } else {
        reader.readAsArrayBuffer(f);
      }
      //procesar el archivo
      blockUI.stop();
    }, 0);
  };


  function saveValues(workbook) {

    var elementsData = [];
    var row = [];

    var first_sheet_name = workbook.SheetNames[0];

    var worksheet = workbook.Sheets[first_sheet_name];

    var limit = XLSX.utils.decode_range(worksheet['!ref']);

    var desired_cell;
    var desired_value;

    for (var x = 0; x <= limit.e.r; x++) {
      for (var j = 0; j <= limit.e.c; j++) {

        var cell_address = {
          c: j,
          r: x
        };

        var cell_ref = XLSX.utils.encode_cell(cell_address);

        desired_cell = worksheet[cell_ref];

        desired_value = (desired_cell ? desired_cell.v : undefined);

        row.push(desired_value);

      }
      elementsData.push(row);
      row = [];
    }


    return elementsData;

  }
});
<html>

<body>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <div class="col-md-6">
    <div>
      <p>Subir Excel de Teradata</p>
      <input type="file" name="teradata" id="teradata" custom-on-change="updloadTeradata" />
    </div>
  </div>
</body>

</html>
    
asked by Aldo 22.03.2018 в 13:17
source

1 answer

0

Synchronous Processing

Most likely the problem is that the code you are running is synchronous, instead of asynchronous.

Try to give the blocking an opportunity to execute, letting the file process be done at a later time in the event queue, that is, instead of:

//Bloqueo de UI
blockUI.start("Cargando...");

//procesar el archivo de forma sincrona

blockUI.stop(); 

Do something like:

//Bloqueo de UI
blockUI.start("Cargando...");

$timeout(function(){
    //procesar el archivo de forma sincrona

    blockUI.stop();
}, 100);

Using the service $timeout instead of setTimeout is to execute the blockUI.stop() within the angular event cycle. And the delay of the 100ms timeout was chosen empirically when testing.

Delay in BlockUI

You also set the delay of blockUI in 0 , in the following way:

processData.config(function(blockUIConfig){
  blockUIConfig.delay = 0;
});

Note that the configuration block is in the method .config() of the module, not in the controller .

FileReader

Now, inspecting the particular code where you load, when using the FileReader in the following way:

var reader = new FileReader();
reader.onload = function(e) {
    //procesar archivo de forma sincrona
}
reader.readAsBinaryString(f);
//o
reader.readAsArrayBuffer(f);

The onload method is actually where you are processing the file and it runs according to the documentation of FileReader asynchronously.

Then it is at the end of that method where you must stop the blocking:

var reader = new FileReader();
reader.onload = function(e) {
    //procesar archivo de forma sincrona

    $timeout(function(){
        blockUI.stop();
    }, 0);
}
reader.readAsBinaryString(f);
//o
reader.readAsArrayBuffer(f);

Notice that we again use $timeout to call blockUI.stop() , this is because the onload method does not run in the angular life cycle.

Demo updated in plunkr

    
answered by 22.03.2018 в 15:52