1

Я реализовал директиву filedrop, которая помещает файл в ngModel.

<filedrop data-ng-model="file"></filedrop> 

Я использую следующий код в мой контроллер:

$scope.$watch('file', function(newVal, oldVal) { 
     if (newVal) { 
      var reader = new FileReader(); 
      reader.onload = function(event) { 
       $scope.parseFile(newVal); 
      }; 
      reader.readAsDataURL(newVal); 
     } 
    }, false); 

В $ scope.parseFile Im фактически разборе XLSX:

$scope.parseFile = function(file) { 
     xlsxParser.parse(file).then(function(data) { 
      console.log("Number of columns", data.datasheet[1].length); 
      console.log("Number of rows", data.datasheet.length); 
      $scope.validationErrors = []; 
      $scope.brand = { 
       items: [] 
      }; 
      $scope.dataItems = []; 
      $scope.datasheetValidate(data.datasheet, $scope.brand); 
      $scope.datasheetData(data.datasheet, $scope.dataItems); 
      if ($scope.validationErrors.length == 0) $scope.validationErrors.push("Nice work, no validation errors"); 
      //$scope.$apply(function(){}); 
     }, function(err) { 
      console.log('error', err); 
     }); 
    } 

Как вы можете см., я прокомментировал //$scope.$apply(function(){}); в корпусе ....

НО, мне это нужно, чтобы обновить мою веб-страницу с изменениями области (например, показать validationErrors)

Почему мне нужен $scope.$apply?

+1

Единственная причина, по которой я вижу, что это произойдет, если 'xlsxParser.parse (файл). Then' не является методом обратного вызова с угловым обещанием. – Chandermani

+0

Ты на самом деле прав. Он использует jQuery. Может потребоваться переписать заимствованный код или принять тот факт, что я должен явно называть заявку :-( –

+0

Отлично, добавив его в качестве ответа, чтобы на вопрос можно было ответить. – Chandermani

ответ

2

Не имеет значения, что вы используете $ scope. $ Watch. Это не помогает, когда вы вызываете $scope.parseFile изнутри reader.onload callback, который находится за пределами области углового.

$scope.$apply следует использовать внутри самого обратного вызова:

reader.onload = function(event) { 
    $scope.$apply(function(){ 
    $scope.parseFile(newVal); 
    }); 
}; 
+0

Я пробовал это, но это не работает. Возможно, из-за комментария, упомянутого Чандермани. Он прав, мне может потребоваться переписать, он использует обещания jQuery. Угадайте, что это происходит, когда вы пытаетесь повторно использовать код других людей. –

0

$scope.$watch и $scope.$apply дополняют друг друга.

$scope.$watch регистрирует новый наблюдатель в области. Всякий раз, когда есть цикл дайджеста, функция часов работает.

$scope.$applyзапускает цикл дайджеста - то есть, если ничего никогда не называл $scope.$apply, не наблюдатели никогда не будет работать вообще.

Для встроенных директив, которые касаются пользовательского ввода (ng-click, ng-keydown и т.д.) и встроенных услуг ($http, $location, $timeout и т.д.), угловых вызовов $scope.$watch для вас. Тем не менее, в любое время, когда вы занимаетесь асинхронным кодом, который живет за пределами этих встроенных директив или служб, вы должны сообщить Angular, что он должен начать новый цикл дайджеста, позвонив по телефону $apply.

Как уже упоминалось, Stewie, вы должны стараться, чтобы ваши звонки $apply были как можно ближе к асинхронной операции; в этом случае это означает использование его на самом верхнем уровне обратного вызова onload.

0

Единственная причина, по которой я вижу это, если xlsxParser.parse (файл). Then не является методом обратного вызова с угловым обещанием.

И как подтверждено @Sander, это действительно не угловатое обещание, поэтому здесь нужно продолжать использовать существующий $ scope. $ Apply call.

+0

Я переписал код, чтобы не использовать обещания вообще, но обратные вызовы, но проблема остается :-( –

+0

Вы пишете обратный вызов не решите проблему, обратный вызов все равно должен быть завернут в '$ scope. $ Apply', чтобы переключиться на angularjs контекст. – Chandermani

+0

У вас есть идея, почему? Я не возражаю оставить «применить» там, но я продолжаю озадачиваться, почему ... Я очень хочу знать –

Смежные вопросы