AngularJS - ForEach不循环

时间:2016-02-21 17:21:20

标签: javascript jquery arrays angularjs foreach

问题

我有一个AngularJS应用程序,由于某种原因,我的一个forEach循环无效。当按钮上的a函数单击时,循环似乎有效,但在初始加载时它不起作用。

代码

所以我正确地为页面设置了控制器。我正在调用我的服务中的一个函数,该函数触发我的API并返回一个数组:

控制器

var holidaysnew = getUserEventsById.getUserEventsById();

服务

app.service('getUserEventsById', function ($http) {  

this.getUserEventsById = function () {
    var holidays = [];


    $http.get("http://localhost:9847/AceTracker.svc/GetAllEventsByUser?user_id=1").success(function (data) {
        for (var key in data.GetAllEventsByUserResult) {
            if (data.GetAllEventsByUserResult.hasOwnProperty(key)) {
                holidays.push(data.GetAllEventsByUserResult[key])
            }
        }
    });
    return holidays;
};
});

因此,在初始页面加载holidaysnew成功命中并且是一系列假期。在我的forEach循环所在的行下方,我想循环遍历holidaysnew,但它似乎没有进入循环。

循环编码如下:

holidaysnew.forEach(function (hol) {
    $scope.eventSources[0].events.push({
        end: $filter('dateFilter')(hol.HOLIDAY_END),
        start: $filter('dateFilter')(hol.HOLIDAY_START),
        title: hol.HOLIDAY_TITLE,
        color: $filter('colorEventFilter')(hol.HOLIDAY_EVENT_STATE_ID)
    });
});

我有console.log holidaysnew数组,它肯定会被填充。有谁能看到这个问题?

编辑:

该服务似乎没问题并按预期返回数组(见下文

enter image description here

但是当$scope.eventSources[0].events = holidayEvents;代码运行时,它实际上似乎并没有设置事件。

holidayEvents是否为数组?

EDIT2:

以下是返回给服务的JSON示例:

{"GetAllEventsByUserResult":[{"HOLIDAY_END":"\/Date(1456358400000+0000)\/","HOLIDAY_EVENT_ID":1,"HOLIDAY_EVENT_STATE_ID":1,"HOLIDAY_START":"\/Date(1455926400000+0000)\/","HOLIDAY_TITLE":"Spain     ","USER_ID":1},{"HOLIDAY_END":"\/Date(1454371200000+0000)\/","HOLIDAY_EVENT_ID":2,"HOLIDAY_EVENT_STATE_ID":2,"HOLIDAY_START":"\/Date(1454284800000+0000)\/","HOLIDAY_TITLE":"Italy     ","USER_ID":1},{"HOLIDAY_END":"\/Date(1458000000000+0000)\/","HOLIDAY_EVENT_ID":3,"HOLIDAY_EVENT_STATE_ID":1,"HOLIDAY_START":"\/Date(1457568000000+0000)\/","HOLIDAY_TITLE":"Germany   ","USER_ID":1},{"HOLIDAY_END":"\/Date(1481068800000+0000)\/","HOLIDAY_EVENT_ID":4,"HOLIDAY_EVENT_STATE_ID":3,"HOLIDAY_START":"\/Date(1480896000000+0000)\/","HOLIDAY_TITLE":"England   ","USER_ID":1}]}

3 个答案:

答案 0 :(得分:1)

这看起来像处理您的REST响应时出错。由于REST调用是异步的,因此数组的填充发生在return语句之后。尝试移动不在其自身功能中的循环,然后在REST成功回调中调用该函数,或者返回Promise并在成功回调中解析它。

回复承诺:

app.service('getUserEventsById', function ($http, $q) {  

    this.getUserEventsById = function () {
        var deferred = $q.defer();
        var holidays = [];


        $http.get("http://localhost:9847/AceTracker.svc/GetAllEventsByUser?user_id=1").then(function (data) {
            for (var key in data.GetAllEventsByUserResult) {
                if (data.GetAllEventsByUserResult.hasOwnProperty(key)) {
                    holidays.push(data.GetAllEventsByUserResult[key])
                }
            }
            deferred.resolve(holidays);
        });
        return deferred.promise;
    };
});

循环承诺:

holidaysnew.then(function(holidays) {
    holidays.forEach(function (hol) {
        $scope.eventSources[0].events.push({
            end: $filter('dateFilter')(hol.HOLIDAY_END),
            start: $filter('dateFilter')(hol.HOLIDAY_START),
            title: hol.HOLIDAY_TITLE,
            color: $filter('colorEventFilter')(hol.HOLIDAY_EVENT_STATE_ID)
        });
    });
});

答案 1 :(得分:1)

更改服务以返回$http承诺,但也要在服务本身中执行所需的所有数据操作,以创建日历事件并返回这些事件。

不推荐使用

success,而是赞成使用then()保证链回调

更传统的方法如下:

app.service('getUserEventsById', function($http, $q) {

  this.getUserEventsById = function() {

    var requestPromise = $http.get("url")
      .then(function(response) {
        var holidays = [];
        var results = response.data.GetAllEventsByUserResult
        for (var key in results) {
          if (results.hasOwnProperty(key)) {
            holidays.push(results[key])
          }
        }
        // return holidays array to next `then()`
        return holidays;
      }).then(function(holidays) {
        var holidayEvents = holidays.map(function(hol) {
          // make sure to inject `$filter` in service
          return {
            end: $filter('dateFilter')(hol.HOLIDAY_END),
            start: $filter('dateFilter')(hol.HOLIDAY_START),
            title: hol.HOLIDAY_TITLE,
            color: $filter('colorEventFilter')(hol.HOLIDAY_EVENT_STATE_ID)
          }

        });
        // return the events array to next `then()`
        return holidayEvents;

      });
    // return the `$http` promise to controller
    return requestPromise;

  };
});

然后在控制器中你需要的只是

getUserEventsById.getUserEventsById().then(function(holidayEvents){
    $scope.eventSources[0].events = holidayEvents;
}).catch(function(){

   // do something if promise chain has a rejection
})

答案 2 :(得分:0)

更好的解决方案/方法是从api进行resolve来电。

angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'yourTemp.html',
            controller: 'Main',
            controllerAs: 'vm',
            resolve: {
                getUserEventsById: function(getUserEventsById){
                    return getUserEventsById.getUserEventsById()
                }
            }
        });
}

angular
    .module('app')
    .controller('Main', Main);

Main.$inject = ['getUserEventsById'];
function Main(getUserEventsById) {
      var vm = this;
      vm.yourdata = getUserEventsById.data;
}

现在,您可以在forEach上运行vm.yourdata循环,这样就可以了。