在填充$ scope数组之前调用的函数

时间:2013-09-14 17:27:29

标签: javascript angularjs

我遇到了AngularJS的问题以及在填充数据数组之前调用的函数。在ng-init中调用我的函数时,$scope.bookings数组尚未被评估(填充数据),导致没有数据。

我的目标是:获取特定预订类型和特定日期的所有预订,并在<td>

中显示所有预订

http://i.imgur.com/GpjemTI.png


这是我的HTML代码:

说明:我遍历所有bookingTypes,然后遍历所有datesng-init执行次数与日期相同,并且有效。 otherBookings应该是该预订类型和该日期的一系列预订。但是,$scope.bookings尚未填充数据,因此永远不会执行otherBookings循环。

<tr ng-repeat="bookingType in bookingTypes">
    <td>{{bookingType.Name}}]</td>
    <td ng-repeat="date in dates" ng-init="otherBookings = checkOtherBookings(bookingType.ID, date)">
        <span ng-repeat="otherBooking in otherBookings">
            <a ng-href="/Bookings/Edit/{{otherBooking.Booking.ID}}"><span >{{otherBooking.Customer.FirstName}}</span></a>
        </span>
    </td>
</tr>

以下是我的JavaScript代码:

说明:BookingsController的顶部,我调用了一个服务,该服务用$scope.bookings数组填充数据,$scope.checkOtherBookings()函数低于:{/ p>

BookingService.getAllBookings().then(function(data) {
    $scope.bookings = data.data;
});

$scope.checkOtherBookings = function(bookingType, date) {
    console.log($scope.bookings);

    var newBookingArray = [];
    for(var i = 0; i < $scope.bookings.length; i++) {
        if($scope.bookings[i].Booking.Type == bookingType) {
            var tmpDateFrom = $scope.bookings[i].Booking.DateFrom;
            var tmpDateTo = $scope.bookings[i].Booking.DateTo;
            if(date >= tmpDateFrom && date <= tmpDateTo) {
                newBookingArray.push($scope.bookings[i]);
            }
        }
    }

    return newBookingArray;
};

$scope.checkOtherBookings()函数被称为 22次(与日期一样多次),但console.log($scope.bookings)正在输出 22次 { {1}} - 所以我的观察是每次调用函数时[]数组都是空的。

我需要某种方法来等待执行$scope.bookings,直到ng-init数组充满数据。

有什么想法吗?


更新1 - 14.09.13

现在$scope.bookings有一些数据,但newBookingArray中的otherBookings永远不会得到它们。

HTML:

ng-init

JavaScript的:

<tr ng-repeat="bookingType in bookingTypes">
    <td>{{bookingType.Name}}</td>
    <td ng-repeat="date in dates" ng-init="otherBookings = checkOtherBookings(bookingType.ID, date)">
        <span ng-repeat="otherBooking in otherBookings">
            <a ng-href="/Bookings/Edit/{{otherBooking.Booking.ID}}"><span >{{otherBooking.Customer.FirstName}}</span></a>
        </span>
    </td>
</tr>

更新2 - 14.09.13

这已经解决了!我将作业从BookingService.getAllBookings().then(function(data) { $scope.bookings = data.data; }); $scope.checkOtherBookings = function(bookingTypeID, date) { var deferred = $q.defer(); $scope.$watch('bookings', function(bookings) { if(!bookings.length) return; var newBookingArray = []; for(var i = 0; i < $scope.bookings.length; i++) { if($scope.bookings[i].Booking.Type == bookingTypeID) { var tmpDateFrom = $scope.bookings[i].Booking.DateFrom; var tmpDateTo = $scope.bookings[i].Booking.DateTo; if(date >= tmpDateFrom && date <= tmpDateTo) { newBookingArray.push($scope.bookings[i]); console.log(JSON.stringify(newBookingArray)); } } } deferred.resolve(newBookingArray); }); return deferred.promise; }; 移到了ng-init,它完美无缺。

HTML:

ng-repeat

JavaScript的:

<tr ng-repeat="bookingType in bookingTypes">
    <td>{{bookingType.Name}}</td>
    <td ng-repeat="date in dates">
        <span ng-repeat="otherBooking in checkOtherBookings(bookingType.ID, date)">
            <a ng-href="/Bookings/Edit/{{otherBooking.Booking.ID}}"><span >{{otherBooking.Customer.FirstName}}</span></a>
        </span>
    </td>
</tr>

1 个答案:

答案 0 :(得分:3)

您可以在checkOtherBookings内返回承诺。 AngularJS解析器自动处理promises。所以你的代码看起来像这样:

$scope.checkOtherBookings = function(bookingType, date) {
    var deferred = $q.defer();
    $scope.$watch('bookings', function(bookings) {
        if (!bookings) return;
        var newBookingArray = [];
        for(var i = 0; i < $scope.bookings.length; i++) {
            if($scope.bookings[i].Booking.Type == bookingType) {
                var tmpDateFrom = $scope.bookings[i].Booking.DateFrom;
                var tmpDateTo = $scope.bookings[i].Booking.DateTo;
                if(date >= tmpDateFrom && date <= tmpDateTo) {
                    newBookingArray.push($scope.bookings[i]);
                }
            }
        }

        deferred.resolve(newBookingArray);
    });
    return deferred.promise;
};

我已经创建了一个在此处演示此技术的plunker:demo link

<强>更新

上述方法适用于AngularJS 1.0.x. AngularJS 1.2RC(可能还有1.1.x)的解析器以不同的方式处理函数返回promise,特别是它不会返回promise,但会立即返回promise的内部$$v,即undefined因为它还没有解决。如果您使用1.2,我建议删除ng-init并尝试以下方法之一。

方法#1:

$scope.$watch('bookings', function(bookings) {
    if (!bookings) return;
    // filter bookings, then set $scope.otherBookings = filteredList
});

方法#2:

$scope.getOtherBookings = function() {
   // return filter list here
}

<span ng-repeat="otherBooking in getOtherBookings()">

方法#3:

<span ng-repeat="otherBooking in bookings | customFilterFunction">