4

AngularJS と、データ配列がいっぱいになる前に呼び出される関数に問題があります。関数が で呼び出されるとng-init$scope.bookings配列は評価されず (データで埋められ)、結果としてデータがありません。

私の目標は:特定の bookingType と特定の日付のすべての予約を取得し、それらすべてを<td>

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


ここに私のHTMLコードがあります:

説明: all をループしてから、 all をループしbookingTypesますdates。はng-init日付と同じ回数実行され、それは機能します。otherBookingsその bookingType とその日付の予約の配列である必要があります。ただし、$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;
};
4

1 に答える 1

3

内で promise を返すことができますcheckOtherBookings。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;
};

ここでテクニックを示すプランカーを作成しました: demo link

更新しました:

上記のアプローチは AngularJS 1.0.x で機能します。AngularJS 1.2RC (およびおそらく 1.1.x) のパーサーは、Promise を返す関数を別の方法で処理します。具体的には、Promise を返さず、Promise の内部$$vをすぐに返します。これはundefined、まだ解決されていないためです。ng-init1.2 を使用している場合は、削除して以下のいずれかの方法を試すことをお勧めします。

アプローチ #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">
于 2013-09-14T17:54:43.197 に答える