我在使用 AngularJS 和一个在填充数据数组之前调用的函数时遇到问题。当我的函数在 ng-init
中被调用时,$scope.bookings
数组还没有被评估(填充数据),导致没有数据。
我的目标是: 获取特定预订类型和特定日期的所有预订,并在 <td>
中显示所有预订
这是我的 HTML 代码:
描述:我遍历所有 bookingTypes
,然后遍历所有 dates
。 ng-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()
函数在下面: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 次 []
- 所以我的观察是每次调用函数时 $scope.bookings
数组都是空的。我需要某种方法来等待执行
ng-init
直到 $scope.bookings
数组充满数据。有任何想法吗?
更新 1 - 14.09.13
现在
newBookingArray
有一些数据,但 otherBookings
中的 ng-init
永远不会得到它们。HTML:
<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:
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;
};
更新 2 - 14.09.13
这就解决了!我将作业从
ng-init
移到了 ng-repeat
,它完美地工作。HTML:
<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>
JavaScript:
BookingService.getAllBookings().then(function(data) {
$scope.bookings = data.data;
});
$scope.checkOtherBookings = function(bookingTypeID, date) {
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(dateInRange(tmpDateFrom, tmpDateTo, date)) {
newBookingArray.push($scope.bookings[i]);
}
}
}
return newBookingArray;
};
最佳答案
您可以在 checkOtherBookings
中返回一个 promise。 AngularJS 解析器会自动处理 promise。所以你的代码看起来像这样:
$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">
关于javascript - 在填充 $scope 数组之前调用的函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18804455/