从 res.send csv 文件中捕获 AngularJS 函数中的响应
Catch the response in AngularJS function from a res.send csv file
我需要从 NodeJS 函数捕获响应(我的意思是检查 NodeJS 函数 return 对客户端的响应,而不是错误)。
单击按钮时,将启动一个带有表单的函数,并且 NodeJS 在查询后 returns 一个 csv 文件。问题是查询很复杂,需要 1+ 分钟才能完成。
我需要在单击按钮时启动加载微调器,并且当 CSV 从函数中 returning 时它应该停止。关于我该怎么做的任何线索?提前致谢。
HTML形式
<form name="csvForm" ng-submit="download(csvForm.$valid)">
<div class="panel-body">
<div class="row">
<div class="form-group col-sm-4">
<label class="control-label">Concessionaria<span ng-if="userProfileID != 1">*</span></label>
<select class="form-control" ng-model="Dealer"
ng-options="dealer.ID as dealer.Name for dealer in dealers "
ng-required="userProfileID != 1">
<option value=""></option>
</select>
</div>
<div class="form-group col-sm-4">
<label class="control-label">Anno*</label>
<select class="form-control" ng-model="Year"
ng-options="y as y for y in syears" required>
<option value=""></option>
</select>
</div>
</div>
</div>
<div class="form-group col-sm-4 col-sm-offset-4" style="margin-top:20px">
<button name="submitBtn" class="btn btn-lg btn-primary btn-block" type="submit" >Scarica CSV</button>
</div>
</form>
Angular
$scope.download = function () {
var form = document.createElement('form');
form.action = apihost + "/queryReport/avanzEvaluation";
form.method = 'POST';
form.target = '_blank';
form.style.display = 'none';
var jsonData = {
dealer: $scope.Dealer,
year: $scope.Year
};
var inputJson = document.createElement('input');
inputJson.type = 'text';
inputJson.name = 'data';
inputJson.value = JSON.stringify(jsonData);
var submit = document.createElement('input');
submit.type = 'submit';
submit.id = 'submitProject';
form.appendChild(inputJson);
form.appendChild(submit);
document.body.appendChild(form);
//Send form.
form.submit();
document.body.removeChild(form);
};
NodeJS
router.post('/avanzEvaluation', function (req, res) {
return new Promise(function(resolve,reject) {
//Not the real query, just an example
var sql = "SELECT * FROM Table ";
return models.sequelize.query(sql, {replacements: replacements, type: models.sequelize.QueryTypes.SELECT })
.then(function (results) {
const Json2csvParser = require('json2csv').Parser;
//Not real fields, just examples
const fields = ["Field1", "Field2", "Field3", "Field4",];
const opts = { fields };
try {
const parser = new Json2csvParser(opts);
const csv = parser.parse(results);
var filename = ("avanzValutazioni.csv");
res.header("Content-Disposition","attachment;filename=" + filename);
res.setHeader('content-type', 'text/csv');
res.send(iconv.encode(csv, 'iso-8859-1'));
}
catch (err) {
console.error(err);
}
})
.catch(function (err) {
console.log(err);
});
})
});
要使用 http 服务启动和停止微调器,请使用 $http
承诺的 .finally
方法:
$scope.spinner = true;
var promise = $http.post(url, data);
promise.finally(function() {
$scope.spinner = false;
});
<div ng-if="spinner">
<!-- Put spinner here -->
</div>
有关详细信息,请参阅
我想出了怎么做,也感谢@georgeawg!
我通过返回带有文件名和完整 csv(csv 格式)的 json 来解决,而不是将其从 NodeJS 函数下载到前端。然后我在前端操纵结果以触发带有结果的 csv 下载。
AngularJS
$scope.download = function () {
//Spinner
usSpinnerService.spin('spinner-1');
//Custom data from the Form, sent as a JSON
var jsonData = {
year: $scope.Year
};
if($scope.Dealer) {
jsonData.dealer = $scope.Dealer;
}
//I've could have done this with a options variable, but i prefer it inline
$http.post(apihost + "/queryReport/avanzEvaluation_TEST", {data: jsonData}, {headers: {'Content-Type': 'application/json'}})
.success(function (result) {
//If the query returns a non-empty csv
if(result.csv.length > 0) {
usSpinnerService.stop('spinner-1');
//This if-else is used to make it work on Edge too
if (window.navigator.msSaveOrOpenBlob) {
var blob = new Blob([result.csv]);
window.navigator.msSaveOrOpenBlob(blob, result.filename);
}
else {
var a = document.createElement("a");
a.href = "data:attachment/csv," + encodeURIComponent(result.csv);
a.target = "_blank";
a.download = result.filename;
document.body.appendChild(a);
a.click();
}
}
//Otherwise I show an error with the module Notification
else {
Notification.error("Non è stato possibile eseguire il download del file CSV.");
}
});
}
NodeJS
router.post('/avanzEvaluation_TEST', function (req, res) {
return new Promise(function(resolve,reject) {
//Not the real query, just an example
var sql = "SELECT * FROM Table ";
return models.sequelize.query(sql, {replacements: replacements, type: models.sequelize.QueryTypes.SELECT })
.then(function (results) {
const Json2csvParser = require('json2csv').Parser;
//Not real fields, just examples
const fields = ["Field1", "Field2", "Field3", "Field4",];
const opts = { fields };
try {
const parser = new Json2csvParser(opts);
const csv = parser.parse(results);
var filename = ("avanzValutazioni.csv");
res.json({filename: filename, csv: csv});
}
catch (err) {
console.error(err);
}
})
.catch(function (err) {
console.log(err);
});
})
});
我需要从 NodeJS 函数捕获响应(我的意思是检查 NodeJS 函数 return 对客户端的响应,而不是错误)。
单击按钮时,将启动一个带有表单的函数,并且 NodeJS 在查询后 returns 一个 csv 文件。问题是查询很复杂,需要 1+ 分钟才能完成。
我需要在单击按钮时启动加载微调器,并且当 CSV 从函数中 returning 时它应该停止。关于我该怎么做的任何线索?提前致谢。
HTML形式
<form name="csvForm" ng-submit="download(csvForm.$valid)">
<div class="panel-body">
<div class="row">
<div class="form-group col-sm-4">
<label class="control-label">Concessionaria<span ng-if="userProfileID != 1">*</span></label>
<select class="form-control" ng-model="Dealer"
ng-options="dealer.ID as dealer.Name for dealer in dealers "
ng-required="userProfileID != 1">
<option value=""></option>
</select>
</div>
<div class="form-group col-sm-4">
<label class="control-label">Anno*</label>
<select class="form-control" ng-model="Year"
ng-options="y as y for y in syears" required>
<option value=""></option>
</select>
</div>
</div>
</div>
<div class="form-group col-sm-4 col-sm-offset-4" style="margin-top:20px">
<button name="submitBtn" class="btn btn-lg btn-primary btn-block" type="submit" >Scarica CSV</button>
</div>
</form>
Angular
$scope.download = function () {
var form = document.createElement('form');
form.action = apihost + "/queryReport/avanzEvaluation";
form.method = 'POST';
form.target = '_blank';
form.style.display = 'none';
var jsonData = {
dealer: $scope.Dealer,
year: $scope.Year
};
var inputJson = document.createElement('input');
inputJson.type = 'text';
inputJson.name = 'data';
inputJson.value = JSON.stringify(jsonData);
var submit = document.createElement('input');
submit.type = 'submit';
submit.id = 'submitProject';
form.appendChild(inputJson);
form.appendChild(submit);
document.body.appendChild(form);
//Send form.
form.submit();
document.body.removeChild(form);
};
NodeJS
router.post('/avanzEvaluation', function (req, res) {
return new Promise(function(resolve,reject) {
//Not the real query, just an example
var sql = "SELECT * FROM Table ";
return models.sequelize.query(sql, {replacements: replacements, type: models.sequelize.QueryTypes.SELECT })
.then(function (results) {
const Json2csvParser = require('json2csv').Parser;
//Not real fields, just examples
const fields = ["Field1", "Field2", "Field3", "Field4",];
const opts = { fields };
try {
const parser = new Json2csvParser(opts);
const csv = parser.parse(results);
var filename = ("avanzValutazioni.csv");
res.header("Content-Disposition","attachment;filename=" + filename);
res.setHeader('content-type', 'text/csv');
res.send(iconv.encode(csv, 'iso-8859-1'));
}
catch (err) {
console.error(err);
}
})
.catch(function (err) {
console.log(err);
});
})
});
要使用 http 服务启动和停止微调器,请使用 $http
承诺的 .finally
方法:
$scope.spinner = true;
var promise = $http.post(url, data);
promise.finally(function() {
$scope.spinner = false;
});
<div ng-if="spinner">
<!-- Put spinner here -->
</div>
有关详细信息,请参阅
我想出了怎么做,也感谢@georgeawg!
我通过返回带有文件名和完整 csv(csv 格式)的 json 来解决,而不是将其从 NodeJS 函数下载到前端。然后我在前端操纵结果以触发带有结果的 csv 下载。
AngularJS
$scope.download = function () {
//Spinner
usSpinnerService.spin('spinner-1');
//Custom data from the Form, sent as a JSON
var jsonData = {
year: $scope.Year
};
if($scope.Dealer) {
jsonData.dealer = $scope.Dealer;
}
//I've could have done this with a options variable, but i prefer it inline
$http.post(apihost + "/queryReport/avanzEvaluation_TEST", {data: jsonData}, {headers: {'Content-Type': 'application/json'}})
.success(function (result) {
//If the query returns a non-empty csv
if(result.csv.length > 0) {
usSpinnerService.stop('spinner-1');
//This if-else is used to make it work on Edge too
if (window.navigator.msSaveOrOpenBlob) {
var blob = new Blob([result.csv]);
window.navigator.msSaveOrOpenBlob(blob, result.filename);
}
else {
var a = document.createElement("a");
a.href = "data:attachment/csv," + encodeURIComponent(result.csv);
a.target = "_blank";
a.download = result.filename;
document.body.appendChild(a);
a.click();
}
}
//Otherwise I show an error with the module Notification
else {
Notification.error("Non è stato possibile eseguire il download del file CSV.");
}
});
}
NodeJS
router.post('/avanzEvaluation_TEST', function (req, res) {
return new Promise(function(resolve,reject) {
//Not the real query, just an example
var sql = "SELECT * FROM Table ";
return models.sequelize.query(sql, {replacements: replacements, type: models.sequelize.QueryTypes.SELECT })
.then(function (results) {
const Json2csvParser = require('json2csv').Parser;
//Not real fields, just examples
const fields = ["Field1", "Field2", "Field3", "Field4",];
const opts = { fields };
try {
const parser = new Json2csvParser(opts);
const csv = parser.parse(results);
var filename = ("avanzValutazioni.csv");
res.json({filename: filename, csv: csv});
}
catch (err) {
console.error(err);
}
})
.catch(function (err) {
console.log(err);
});
})
});