AngularJS,Factory,$ scope和promise奋斗

时间:2015-12-16 23:55:07

标签: 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) + "%");

          });
        };

跟踪上传的进度并成功输出到控制台的百分比,我想要实现的是将进度百分比传递给调用此服务的控制器,我正在努力尝试一下,考虑到我已经有了一个承诺到位,不确定如何正确抓取文本,这里我的尝试是$rootscope.text并在我的控制器中设置一个手表并且它有效但是有更优雅/正确的方式吗? / p>

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

2 个答案:

答案 0 :(得分:1)

看起来$ broadcast功能可能在这里很好用。查看这篇文章,找到解释清楚的答案:$on and $broadcast in angular

您可以在here

找到$ broadcast和$的文档

答案 1 :(得分:1)

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

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!');
    });