javascript - AngularJS、Factory、$scope 和 Promise 之争

标签 javascript angularjs angularjs-scope promise

所以我对下面的代码遇到了一些困难:

app.factory('sfAttachment', ['$http', '$q', '$window', '$rootScope', function($http, $q, $window, $rootScope) {

  var attachment = {};
  //Save to server function for attachments
  attachment.save = function(base64value, document, index) {

    /*Stripping the file type text in front of the base64 
      string, without this the file would show as corrupted */
    var position = base64value.indexOf("base64,");
    var matchWord = "base64,";
    var base64valueClean = base64value.slice(position + matchWord.length, base64value.length);

    //Setting payload to be saved in SF database.
    var data = {
      "Body": base64valueClean,
      "ContentType": document.attachmentContentType,
      "ParentId": document.id,
      "Name": document.fileName
    };

    /*Get the {!URLFOR('/services/data/v26.0/sobjects/Attachment/')} value
      cannot be processed on static ressource, hence the link to the window
      global variable.*/
    var url = $window.__url;
    var method = 'POST';

    var request = {

      url: url,
      method: method,
      data: data,
      headers: {
            __XHR__: function() {
                return function(xhr) {
                    xhr.upload.addEventListener("progress", function(event) {

                      $rootScope.text = event.loaded/event.total;
                      $rootScope.$apply();
                        console.log("uploaded " + ((event.loaded/event.total) * 100) + "%");

                    });
                };
            }
        }
    };

    console.log(request);

    //Promise type approach to Http request, allows easy handle of succes and failure
    // Very useful for asynchronous calls.
    var deferred = $q.defer();

    //Performing http request to Server
    $http(request).then(function(response) {

      deferred.resolve(response);
      console.log('File UPLOADED to SF!');

    }, function(event) {

      //Need to Improve error handling!!!
      deferred.reject('The attachment could not be saved:' + event);

    });


    return deferred.promise;
  }

此服务的目的是将附件加载到 Salesforce 中,效果很好,但后来我添加了一段代码

headers: {
    __XHR__: function() {
        return function(xhr) {
          xhr.upload.addEventListener("progress", function(event) {

            $rootScope.text = event.loaded / event.total;
            $rootScope.$apply();
            console.log("uploaded " + ((event.loaded / event.total) * 100) + "%");

          });
        };

要跟踪上传进度并成功将百分比输出到控制台,我想要实现的是将进度百分比传递给调用此服务的 Controller ,考虑到我已经有,我对此有点挣扎一个 promise ,不太确定如何正确抓取文本,这里我的尝试是使用 $rootscope.text 并在我的 Controller 中设置一个 watch ,它可以工作,但是有没有更优雅/合适的这样做的方法?

$rootScope.$watch('text', function(newValue, oldValue, scope) {
  console.log($rootScope.text);
});

最佳答案

Angular 的 $q promise 确实提供了提供进度更新的工具。您应该能够构建这样的 promise :

app.factory('sfAttachment', [
    '$http', '$q', '$window', '$rootScope', function ($http, $q, $window, $rootScope) {

        var attachment = {};
        //Save to server function for attachments
        attachment.save = function (base64value, document, index) {

            /*Stripping the file type text in front of the base64 
              string, without this the file would show as corrupted */
            var position = base64value.indexOf("base64,");
            var matchWord = "base64,";
            var base64valueClean = base64value.slice(position + matchWord.length, base64value.length);

            //Setting payload to be saved in SF database.
            var data = {
                "Body": base64valueClean,
                "ContentType": document.attachmentContentType,
                "ParentId": document.id,
                "Name": document.fileName
            };

            /*Get the {!URLFOR('/services/data/v26.0/sobjects/Attachment/')} value
              cannot be processed on static ressource, hence the link to the window
              global variable.*/
            var url = $window.__url;
            var method = 'POST';

            var deferred = $q.defer();

            var request = {
                url: url,
                method: method,
                data: data,
                headers: {
                    __XHR__: function () {
                        return function (xhr) {
                            xhr.upload.addEventListener("progress", function (event) {
                                var pct = event.loaded / event.total;
                                // notify here
                                deferred.notify(pct);
                                console.log("uploaded " + (pct * 100) + "%");
                            });
                        };
                    }
                }
            };

            $http(request).then(function (result) {
                deferred.resolve(result);
            }, function (error) {
                deferred.reject(error);
            });

            return deferred.promise;
        };

        return attachment;
    }
]);

然后你可以像这样使用它:

sfAttachment.save(value, document, index)
    .then(function (result) {
        console.log('finished downloading');
    },
    null,
    function (pct) {
        $scope.downloadPct = pct;
    })
    .catch(function (error) {
        console.log('oh noes!');
    });

链接两个文件上传:

sfAttachment.save(file1, document, index)
    .then(function (result) {
        return sfAttachment.save(file2, document, index);
    }, null, function (pct) {
        $scope.downloadPct = pct;
    })
    .then(null, null, function (pct) {
        $scope.downloadPct2 = pct;
    })
    .catch(function (error) {
        console.log('oh noes!');
    });

关于javascript - AngularJS、Factory、$scope 和 Promise 之争,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34324368/

相关文章:

javascript - Angularjs 阻止页面加载并在点击时显示值

javascript - Protractor - 如何在配置文件中排除 spec 文件?

javascript - 基于 JS/HTML5 Webkit 的移动开发的轻量级 UI 框架,具有良好的列表性能

javascript - 在Papaparser中,如何处理多个值?

JavaScript for 内循环

javascript - 从内部函数更改 AngularJS 作用域变量

javascript - 如何仅使用一个变量反转字符串

angularjs - 为什么指令有作用域?

javascript - 更改函数中的 ng-repeat 范围不会更新范围

javascript - ng 样式/动态照片网格上的 Angular 摘要循环