当数据准备就绪时,Angularjs会回避

时间:2017-02-11 13:55:54

标签: javascript angularjs asynchronous

我正在使用.Net后端开发我的第一个角度应用程序。

我使用http.post从web方法获取数据异步。一切正常。 客户端我想做一些简单的计算(表中的最后一行包含表中所有数据的总和)

执行此操作的代码非常简单,但我的问题是我尝试执行此操作时尚未准备好的数据。

我读过我可以使用承诺,服务或工厂。但我不确定我们最好的方式。

我的观点代码:

<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.SprintViewModel?

2 个答案:

答案 0 :(得分:1)

您可以将ng-if条件添加到最后<tr>,当数据准备填充到您的控制器中时,该条件将解析为true。因此,您最初可以定义$scope.loading = false,一旦您的代码准备就绪,您就可以设置$scope.loading=true并在内部调用$ digest循环,并且您的视图会更新。

答案 1 :(得分:0)

你可以做几件事。我已经通过在函数中放置保护条件来解决这类问题。这些检查在继续之前检查了必要的变量。因此,在函数开头添加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;
    }

这是另一种选择,但正如你已经提到的那样,我认为promises和$q库是正确的角色方式来修复这种事情。