使用新的键和值AngularJS计算并附加JSON

时间:2015-05-12 04:21:06

标签: javascript json angularjs

所以我有一堆JSON数据,我想做一些计算并附加结果并在JSON中创建一个新密钥。我已经设置了计算服务,然后我在控制器中使用它。但问题是,它只是将最后已知的值推入每个新创建的“费率”键中。

JSON是这样的:

[{  "date"      : "2015-09-01",
"start"     : "2015-09-01 08:00:00",
"finish"    : "2015-09-01 10:00:00",
"loggedIn"  : "2015-09-01 08:06:27",
"loggedOut" : "2015-09-01 10:06:27"

}, { "date"      : "2015-09-02",
 "start"     : "2015-09-02 08:00:00",
 "finish"    : "2015-09-02 10:00:00",
 "loggedIn"  : "2015-09-02 08:02:05",
 "loggedOut" : "2015-09-02 10:02:11"

}, { "date"      : "2015-09-03",
 "start"     : "2015-09-03 13:00:00",
 "finish"    : "2015-09-03 14:30:00",
 "loggedIn"  : "2015-09-03 13:11:05",
 "loggedOut" : "2015-09-03 14:31:01"

}, { "date"      : "2015-09-04",
 "start"     : "2015-09-04 13:00:00",
 "finish"    : "2015-09-04 14:30:00",
 "loggedIn"  : "2015-09-04 13:01:05",
 "loggedOut" : "2015-09-04 14:31:01"

}, { "date"      : "2015-09-05",
 "start"     : "2015-09-05 18:00:00",
 "finish"    : "2015-09-05 21:00:00",
 "loggedIn"  : "2015-09-05 18:30:05",
 "loggedOut" : "2015-09-05 21:00:51"

}]

服务如下:

angular.module('appService', [])
.service('CalculationService', function(){
    this.getTheRate = function(start, end, login) {
        if ( typeof (start) && typeof (end) && typeof (login) === 'undefined') {
            return 'n/a';
        } else {
            var startTime =  new Date(start).getTime() / 60000,
                endTime   =  new Date(end).getTime()   / 60000,
                loginTime =  new Date(login).getTime() / 60000;

            var totalTime  = endTime - startTime,
                lateness   = loginTime - startTime,
                percentile = 100 - (lateness / totalTime) * 100;

            return parseFloat(percentile).toFixed(1);
        }
    };

控制器是这样的:

angular.module('MainController', [])
 .controller('mainCtrl', [
    '$http', 
    'CalculationService', 
    function($http, CalculationService){

         var logins = this;

         logins.dataStore = [];

         logins.add = function(temp){
             logins.dataStore.push(temp);
         };

         $http.get('./theData.json').success(function(data){
            logins.data = [];
            logins.data = data;
         });

         logins.getRate = function(start, end, login) {
            angular.forEach(logins.data, function(obj){
                obj.rate = {};
                obj.rate = CalculationService.getTheRate(start, end, login);
                return obj.rate;
            });
         };
}]);

标记如下:

<div ng-controller="mainCtrl as main">
<section class="view-section">
            <div class="view" ng-repeat="item in main.data"> 
                {{ main.getRate(item.start, item.finish, item.loggedIn) }}
                {{ item.rate }}
            </div>
</section>
</div>

{{item.rate}}在ngRepeat中输出正常但是当我通过{{main.data}}检查数据时,为每个实例创建了密钥但是没有正确插入值,因此所有'rate'密钥为每个实例分配相同的最后已知计算值而不是不同的计算值。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您的getRate函数会循环调用所有数据(使用angular.forEach),但使用相同的startfinishlogin值。然后在ngRepeat内调用此函数,创建第二个循环。因此ngRepeat循环的每次迭代都会将当前项的速率分配给所有项。这就是为什么当你完成时,所有项目都有最后一项的费率。

相反,在获取数据之后立即调用控制器中的速率计算循环(在logins.data回调中分配$http.get后),而不是{{...}}表达式中。正如评论所提到的,在表达式中调用具有副作用的函数并不是一个好主意。

另请注意,此错误是可能的,因为您的getRate函数都会将速率分配给对象(实际上,分配给所有对象)并返回它。这令人困惑且容易出错。如果函数分配率或返回它,但不是两者都会更容易。