2015-12-16 3 views
0

Так что я имею некоторую борьбу с ниже кодом:

цели
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 и настройка часов в моем контроллере, и это работает, но есть ли более элегантный/правильный способ сделать это?

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

ли вы рассмотреть используя '$ rootScope. $ broadcast (" sfProgress ", event)'? https://docs.angularjs.org/api/ng/type/$rootScope.Scope – georgeawg

+0

Еще одно обещание не поможет вам в этой ситуации - обещания не предназначены для сценариев типа «прогресс». –

ответ

1

$q обещает ANGULAR в предоставляют средство для предоставления информации о ходе работ. Вы должны быть в состоянии построить такое обещание, как это:

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

Это действительно полезно, спасибо @JLRishe, почему использование catch во втором фрагменте? почему бы не обработать ошибку, где вместо этого нуль? в чем причина того, что у вас есть нуль? – Tekill

+0

Также не нужен '$ q.defer', и если да, то почему? – Tekill

+1

@Yourinium Подход, который я использовал, позволяет поймать любые ошибки, которые происходят в обработчике '.then()'. Использование '.then (success, fail)' известно как ['.then (успех, неудача)' antipattern] (https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the -thensuccess-fail-anti-pattern) и обескуражен, потому что он не является идиоматическим и может привести к ошибкам, которые не удалось выполнить. – JLRishe

1

Похоже, что функция широковещания $ может служить вам хорошо здесь. Проверьте этот пост хорошо объяснил ответ: $on and $broadcast in angular

Вы можете найти в документации по $ вещания и $ на here

+0

Мысль об этом и да, я мог бы использовать это, но я надеялся на что-то подобное, как на ответ @ JLRishe. Спасибо, хотя за предложение – Tekill

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