Nano Hash - криптовалюты, майнинг, программирование

Фабрика Angular: область обновления с прогрессом во время загрузки

Я написал фабрику Angular, которая обрабатывает загрузку на S3:

'use strict';

angular.module('myApp.s3', [])
    .factory('S3', function ($q) {
        var aws = { ... }

        var progress = 0;

        function getFileName(fileURI) {
            return fileURI.split('/').pop();
        }

        return {
            progress: progress,
            upload: function (fileKey, fileURI, mimeType) {
                var fileName = getFileName(fileURI);
                if (fileName === '') {
                    console.log('File name can\'t be empty');
                    return;
                }

                var defer = $q.defer();
                defer.promise.then(function (event) {
                    alert(JSON.stringify(event));
                    console.log(event);
                }, function (error) {
                    alert(JSON.stringify(error));
                    console.log(error);
                });

                var fileTransfer = new FileTransfer();
                var fileUploadOptions = new FileUploadOptions();
                fileUploadOptions.fileKey = 'file';
                fileUploadOptions.fileName = fileName;
                fileUploadOptions.chunkedMode = false;
                fileUploadOptions.params = {
                    'key': fileKey,
                    'AWSAccessKeyId': aws.access_key_id,
                    'acl': aws.acl,
                    'policy': aws.policy,
                    'signature': aws.signature
                };

                fileTransfer.upload(fileURI, encodeURI('https://' + aws.bucket + '.s3.amazonaws.com/'),
                    defer.resolve, defer.reject, fileUploadOptions);
                fileTransfer.onprogress = function (progressEvent) {
                    if (progressEvent.lengthComputable) {
                        progress = (progressEvent.loaded / progressEvent.total) * 100;
                        console.log(progress);
                    } else {
                        //loadingStatus.increment();
                    }
                };

                return defer.promise();
            }
        };
    });

Этот код работает нормально, и файл загружается на S3. Журнал прогресса тоже работает. Когда я использую эту фабрику в контроллере и привязываю прогресс к области, я не вижу обновлений хода выполнения в своей области. Я предполагаю, что это связано с тем, что область не получает событие обновления.

Я видел обходной путь, когда фабрика инициализируется с областью действия, а внутри фабрики вызывается scope.apply(). Я не думаю, что это правильный способ сделать это в Angular, но я тоже не знаю правильного пути. Какие-нибудь советы?


Ответы:


1

Ответ @Dmitry Tolmachov определенно сработает, но я бы использовал defer.notify, потому что вы уже используете обещание и потому, что с помощью уведомления вам не нужно вручную вызывать цикл дайджеста:

fileTransfer.onprogress = function (progressEvent) {
    if (progressEvent.lengthComputable) {
        progress = (progressEvent.loaded / progressEvent.total) * 100;
        console.log(progress);
        defer.notify(progress);
    } else {
        //loadingStatus.increment();
    }
};

А затем используйте его в своем контроллере. Затем (успех, ошибка, уведомление)

cf : Событие выполнения POST службы HTTP Angularjs

04.09.2015
  • Да! Я только что обнаружил, что это возможно, и я думаю, что это даже лучше! Спасибо! 04.09.2015

  • 2

    Проблема здесь в том, что когда вызывается fileTransfer.onprogress, он не запускает цикл дайджеста. Я настоятельно рекомендую прочитать эту статью: http://www.sitepoint.com/understanding-angulars-apply-digest/

    Что касается решения, то одним из простых способов будет:

    1) Вставьте $rootScope в фабрику:

    .factory('S3', function ($q, $rootScope) {
    

    2) Запустите цикл дайджеста вручную:

    progress = (progressEvent.loaded / progressEvent.total) * 100;
                        console.log(progress);
    $rootScope.$digest();
    

    Это должно исправить это.

    04.09.2015
  • Спасибо! Это работает, как и ожидалось! Но разве я не должен вместо этого вызывать $apply()? В предоставленной вами статье явно вызывается только функция $apply(). 04.09.2015
  • Для rootScope это не имеет значения, если вы посмотрите официальную документацию для scope.apply, вы увидите, что: function $apply(expr) { try { return $eval(expr); } поймать (e) { $exceptionHandler(e); } наконец { $root.$digest(); } } Таким образом, $rootScope.$digest вызывается в любом случае, но цель $apply — запустить некоторый код и запустить дайджест после него. 04.09.2015
  • Однако для обычного $scope это имеет значение, так как $scope.$digest() будет обновлять представление и запускать наблюдатели только для этого $scope. При запуске $scope.$apply() будет обновлять все приложение как обычно. 04.09.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..