2013-06-17 4 views
4

J'ai un service qui génère un fichier CSV et le renvoie à la page via un http/ajax get. J'aimerais que l'utilisateur clique sur un bouton, appelle le service, puis télécharge le fichier dans le navigateur de l'utilisateur.Utilisation d'Angular pour télécharger un fichier via Ajax

Je voudrais faire ceci La Voie Angulaire, bien que je reconnaisse que cela puisse avoir plus à faire avec Ajax ou le navigateur qu'Anguler en soi.

Le service est en C#, et voici ce qu'elle retourne:

return File(Encoding.UTF8.GetBytes(WriteCSV(assetList)), "text/csv", "results.csv"); 

Le code du contrôleur qui appelle le service se présente comme suit. Il fonctionne, mais je ne sais pas quoi faire en cas de succès:

$scope.exportCSV = function() { 
    $http({ 
     method: "get", 
     url: "ExportCSV" 
    }). 
     error(function (data, status, headers, config) { 
      alert("Error exporting data to CSV."); 
     }); 
}; 
+0

pouvez-vous utiliser html5filesystem? –

Répondre

5

Vous ne pouvez pas lancer un téléchargement à partir d'un GET ou POST ajax normale, vous devez faire de manière traditionnelle, par exemple window.location='url' et définir la corriger l'en-tête http avec le type de contenu correct qui affichera la boîte de dialogue de téléchargement dans le navigateur de l'utilisateur

2

Peut-être un moyen plus «angulaire» est d'avoir votre contrôleur mis un drapeau pour déclencher le téléchargement, mais mettre la fonctionnalité de base dans un directive qui construit un élément avec un attribut "download", et à l'affichage, un callback/watch appelle le ng-clic.

Par exemple:

// put this in a template related to a given controller 
<downloader ng-if="downloadready"></downloader> 

// controller just needs to trigger the directive into action 
module.controller(..., function($scope){ 
    $scope.downloadready = true; // trigger the directive to be created  
}); 

// and the directive code will build the element and click the button 
module.directive('downloader', function ($compile) { 
    return { 
      restrict: 'E', 
      replace: true, 
      // values here can be placed in the template as variables and accessed in link() 
      // but this is shortest to get the idea across 
      template: '<a id="downloadbtn" class="btn" download="backup.json"></a>', 
      link:function (scope, elm, attrs) { 
       // this clicks the button outside the digest loop which the scope was updated in 
       $timeout(function() { 
       angular.element($('#downloadbtn')).triggerHandler('click'); 
       }, 0); 
      } 
    } 
}); 

Bien que je l'avoue, il est cintrer esprit plus que de changer redirect sur document.location.

Questions connexes