我有一些AJAX调用需要为数组中的每个条目运行,我试图提供一些关于循环通过数组的进度的视觉反馈,模型正在正确更新但我'我没有在视图中看到任何更新,试图在循环中调用$ digest对DOM没有影响。
我尝试在内循环中添加$ apply到函数但我仍然没有看到变化。
$scope.UploadEntry = function(item){
var oDBGet = new htmldb_Get(null,
$v('pFlowId'),
"APPLICATION_PROCESS=UploadTargetDates",
$v('pFlowStepId'));
oDBGet.add('EX_TRD',$scope.Ext.TRDDate.val);
oDBGet.add('EX_MAX_TRD',$scope.Ext.MaxTRDDate.val);
oDBGet.add('EX_READ',Ext.ReadDownloadCheck);
oDBGet.get();
};
$scope.ShowUploadModal = true;
$scope.UploadDone = 0;
for(i in submissionList)
{
$scope.UploadEntry(submissionList[i]);
$scope.UploadDone += 1;
}
$scope.ShowUploadModal = false;
但是观点:
<div class="UploadModal" ng-show="ShowUploadModal">
Uploading entries: {{UploadDone}} complete
</div>
从未看到条目已上传,但如果我从循环结束时取出$scope.ShowUploadModal = false;
,则会在循环结束时显示。
答案 0 :(得分:1)
<强>更新强>
经过讨论,作者声明http请求是同步的。问题仍然是“同步”,但有点小问题。看看Angular digest concepts。它基本上运行所有观察者,表达式(绑定)并一遍又一遍地处理所有$evalAsync
,直到手表结果和表达式不再发生变化。在此之后,DOM被更新。
因此,问题是所有的同步请求都在摘要周期结束之前得到解决,而DOM呈现只会在摘要周期结束处理后才会发生。
解决问题的最简单方法,就是说你无法更改API来调用异步,就是确保你的请求是异步的,抓住他们的承诺,只有当所有这些都隐藏了uploadModal时已经完成(这可以通过promises API实现,阅读promises API和$timeout
)。像这样:
var loadingPromises = [];
$scope.ShowUploadModal = true;
$scope.UploadDone = 0;
for(i in submissionList) {
loadingPromises.push($timeout((function(index) {
return function() {
$scope.UploadEntry(submissionList[index]);
$scope.UploadDone += 1;
};
})(i), 0));
}
$q.all(loadingPromises).then(function() {
$scope.ShowUPloadMOdel = false;
});
请注意我创建的闭包,以确保将正确的索引传递给请求,并且您需要向控制器注入$q
服务。虽然这将解决您的问题,您应该创建一个服务并在那里移动您的加载逻辑,返回一个promise(将$ scope引用更改为参数):
app.service('yourLoaderService', function($timeout) {
this.load = function(url) {
return $timeout(function() {
var oDBGet = new htmldb_Get(null,
$v('pFlowId'),
"APPLICATION_PROCESS=UploadTargetDates",
$v('pFlowStepId'));
oDBGet.add('EX_TRD',$scope.Ext.TRDDate.val);
oDBGet.add('EX_MAX_TRD',$scope.Ext.MaxTRDDate.val);
oDBGet.add('EX_READ',Ext.ReadDownloadCheck);
oDBGet.get();
}, 0);
};
});
你的控制器:
var loadingPromises = [];
$scope.ShowUploadModal = true;
$scope.UploadDone = 0;
for(i in submissionList) {
var promise = yourLoaderService.load(submissionList[i]).then(function() {
$scope.UploadDone++;
});
loadingPromises.push(promise);
}
$q.all(loadingPromises).then(function() {
$scope.ShowUPloadMOdel = false;
});
第一个回答
这是一个概念错误。你似乎来自同步服务器端的背景,也许是Python,我不知道。如果这是您的真实代码,那么问题是您的代码是完全同步的。您正在显示上传模型,循环所有条目并隐藏模型,整个代码在DOM渲染甚至一次之前都以毫秒(或更少)的速度发生。
这是因为当您要求上传时,Javascript不会挂起上传过程,它只是要求并继续。您可以找到有关异步编程here,here,here和here的内容。
您必须在上传回调中连接上传的计数。我不知道您上传了什么,但是$scope.uploadEntry
将返回promise,然后等待它完成并更新计数。
$scope.ShowUploadModal = true;
$scope.UploadDone = 0;
for(i in submissionList)
{
$scope.UploadEntry(submissionList[i]).then(function() {
$scope.UploadDone += 1;
scope.ShowUploadModal = $scope.UploadDone !== submissionList.length;
});
}
如果您使用$http
作为uypload作业,只需返回它,因为它已经是一个承诺并且每.then(funciton
更改.success(function
。如果没有,这将会更加复杂,您需要阅读Angular docs on promises。
只是旁注,你应该看看Javascript命名对话。 Javascript通常假设cammelCase
个变量,而不是PascalCase
。这是David Crackford's convetion。