我正在开发我的第一个带有.Net后端的angular应用程序。
我使用 http.post 从网络方法异步获取数据。这一切都很好。客户端我想做一些简单的计算(表中的最后一行,其中包含表中所有数据的总和(
执行此操作的代码非常简单,但我的问题是当我尝试这样做时我还没有准备好的数据。
我读到我可以使用承诺和服务或工厂。但我不确定我们最好的方式是什么。
我的视图代码:
<div ng-controller="taskCtrl as ctrl">
<div class="col-md-10 container outer">
<h1 class="center-block">{{ctrl.SprintViewModel.SprintName}}</h1>
<table id="SprintMetaDate">
<tr><td>Projekt:</td><td>{{ctrl.SprintViewModel.ProjektName}}</td></tr>
<tr><td>Periode:</td><td>{{ctrl.SprintViewModel.StartDate}} - {{Ctrl.SprintViewModel.EndDate}}</td></tr>
<tr><td>Udarbejdet af/d:</td><td>{{ctrl.SprintViewModel.MadeBy}}</td></tr>
</table>
<h3>Sprint Resume:</h3>
<br/>
{{ctrl.SprintViewModel.SprintResume}}
<h3>Sprint afslutning:</h3>
{{ctrl.SprintViewModel.SprintDemo}}
<h2>Scope og Økonomi </h2>
<h3>Sprint Opgaver</h3>
<table id="SprintTasks" class="col-md-12">
<tr><th>Opgave</th><th>Estimat</th><th>Forbrug</th><th>Udest.</th><th>*</th><th>Pris (DKK)</th></tr>
<tr ng-repeat="x in ctrl.SprintViewModel.Tasks">
<td style="width: 40%">{{ x.Description }}</td>
<td>{{ x.TimeEst }}</td>
<td>{{ x.TimeUsed }}</td>
<td>{{ x.TimeRemaining }}</td>
<td>{{ ctrl.CalcPrecisionOfEstimat(x.TimeUsed,x.TimeRemaining,x.TimeEst) | number:2}} %</td>
<td>{{x.Price}}</td>
</tr>
<tr>
<td>Ialt</td>
<td>{{ ctrl.TotalEstimat() }}</td>
<td>{{ ctrl.TotalTimeUsed() }}</td>
<td>{{ctrl.TotalTimeRemaining()}}</td>
<td>{{ctrl.TotalPrecision()}}</td>
<td>{{ctrl.TotalPrice()}}</td>
</tr>
</table>
* Forbrug + Udestående i forhold til estimat
<br/>
Udestående opgaver er planlagt ind i næstkommende sprint.
</div>
</div>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('taskCtrl', function($scope, $http) {
var ctrl = this;
ctrl.SprintViewModel = null;
ctrl.TotalEstimat=function() {
var totalEstimat=0;
for (i=0; i<ctrl.SprintViewModel.Tasks.count;i++) {
totalEstimat += ctrl.SprintViewModel.Tasks[i].Estimate;
}
return totalEstimat;
}
ctrl.TotalPrecision = function () {
var totalPrecision=0;
angular.forEach(ctrl.SprintViewModel.Tasks, function (value, key) {
totalPrecision += Number(value);
});
$http.post('SprintRapport.aspx/GetSprintViewModel', {})
.then(function(response, status, headers, config) {
console.log("I success");
ctrl.SprintViewModel = response.data.d;
});
});`
如前所述,每次在最后一行的所有方法上加载页面时,我都会得到一个 null引用,因为 ctrl。SprintviewModel 未定义。为了简单起见,我只包括了其中一种方法,所有方法的问题都是一样的。
所以我的问题是如何确保 ctrl。TotalEstimat(( 首先被调用,然后 ctrl。SprintView模型已分配?
您可以将ng-if
条件添加到最后一个<tr>
,当数据准备好填充到控制器中时,该条件解析为 true。因此,您可以最初定义$scope.loading = false
,一旦代码准备好填充,就可以设置$scope.loading=true
,这将在内部调用$digest循环并更新视图。
你可以做几件事。我已经通过在函数中放置保护条件来修复此类问题。在继续之前,这些检查是否已设置必要的变量。因此,在函数的开头添加if (!ctrl.SprintViewModel) return;
如下:
ctrl.TotalEstimat=function() {
// Guard Condition to prevent function executing in invalid state.
if (!ctrl.SprintViewModel) return;
var totalEstimat=0;
for (i=0; i<ctrl.SprintViewModel.Tasks.count;i++) {
totalEstimat += ctrl.SprintViewModel.Tasks[i].Estimate;
}
return totalEstimat;
}
这是另一种选择,但正如您已经提到的,我认为承诺和$q
库是解决此类问题的适当角度方法。