循环进度的AngularJS DOM更新

循环进度的AngularJS DOM更新,dom,for-loop,angularjs,Dom,For Loop,Angularjs,我有很多AJAX调用需要为数组中的每个条目运行,我试图提供一些关于数组中循环进度的视觉反馈,模型正在正确更新,但我没有看到视图中的任何更新尝试在循环中调用$digest对DOM没有影响 我已经尝试向内部循环中的函数添加$apply,但仍然没有看到任何变化 $scope.UploadEntry = function(item){ var oDBGet = new htmldb_Get(null, $v('pFlowId'),

我有很多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>

上载条目:{UploadDone}}完成

从未在上传条目时看到,但如果我采用
$scope.ShowUploadModal=false,则在循环结束时显示从循环结束处退出。

更新

经过讨论,作者声明http请求是同步的。问题仍然是关于“同步性”,但有点诡计。看一看。它基本上运行所有的观察者、表达式(绑定)并反复处理所有的
$evalAsync
,直到观察结果和表达式不再发生变化。在此之后,DOM将被更新

因此,问题在于,所有同步请求都是在摘要周期结束之前解决的,而DOM呈现只会在摘要周期完成处理之后发生

解决问题的最简单方法是,当您声明无法将API更改为调用async时,确保您的请求是异步的,获取它们的承诺,并且仅在所有请求都完成时隐藏uploadModal(这可以通过Promissions API、read and来实现)。像这样:

var-loadingPromises=[];
$scope.ShowUploadModal=true;
$scope.UploadDone=0;
对于(提交清单中的我){
loadingPromises.push($timeout((函数(索引))的{
返回函数(){
$scope.UploadEntry(提交列表[索引]);
$scope.UploadDone+=1;
};
})(i) ,0);
}
$q.all(加载承诺)。然后(函数(){
$scope.ShowUPloadMOdel=false;
});
请注意,我创建的闭包是为了确保将正确的索引传递给请求,您需要向控制器注入
$q
服务。尽管这将解决您的问题,您应该创建一个服务并将加载逻辑移到那里,返回一个承诺(将$scope引用更改为参数):

app.service('yourLoaderService',函数($timeout){
this.load=函数(url){
返回$timeout(函数(){
var oDBGet=new htmldb_Get(null,
$v('pFlowId'),
“应用程序进程=上传目标日期”,
$v('pFlowStepId');
oDBGet.add('EX_TRD',$scope.Ext.TRDDate.val);
oDBGet.add('EX_MAX_TRD',$scope.Ext.maxtrdate.val);
oDBGet.add('EX_READ',Ext.ReadDownloadCheck);
oDBGet.get();
}, 0);
};
});
和您的控制器:

var-loadingPromises=[];
$scope.ShowUploadModal=true;
$scope.UploadDone=0;
对于(提交清单中的我){
var promise=yourLoaderService.load(submissionList[i]),然后(function(){
$scope.UploadDone++;
});
加载承诺。推送(承诺);
}
$q.all(加载承诺)。然后(函数(){
$scope.ShowUPloadMOdel=false;
});

第一个答案

这是一个概念错误。您似乎来自同步服务器端背景,可能是Python,我不知道。如果这是您真正的代码,那么问题是您的代码是完全同步的。您正在显示上载模型,循环所有条目并隐藏模型,而整个代码在DOM渲染一次之前的毫秒(或更短)内完成

这是因为当您请求上传时,Javascript不会挂起上传过程,它只是请求并继续。您可以找到有关异步编程的内容,以及

您必须在上载回调中连接上载计数。我不知道你用什么上传,但是你的
$scope.uploadEntry
将返回一个,然后你等待它完成并更新计数

$scope.ShowUploadModal=true;
$scope.UploadDone=0;
对于(提交清单中的我)
{
$scope.UploadEntry(submissionList[i])。然后(function(){
$scope.UploadDone+=1;
scope.ShowUploadModal=$scope.UploadDone!==submissionList.length;
});
}
如果您正在使用
$http
进行uypload作业,只需返回它,因为它已经是一个承诺并进行了更改
。然后(function
per
).success(function
。如果不是,这将有点复杂,您需要阅读


顺便说一句,您应该看看Javascript命名转换。Javascript通常假定
cammelCase
变量,而不是
PascalCase
。以下是。

我知道异步JS回调,并希望它能像此方法那样锁定UI,但不幸的是,在这种情况下,包装它的框架是ajax calls作为同步操作,我知道这很可怕,但是几乎没有机会改变它。你能发布你的uploadEntry函数吗?好的,这个例子现在已经修改了。你完全确定上传进度不同步吗?在你的循环中放一个
控制台。记录
,看看它运行得有多快。用解决方案编辑了这个问题。