0

データが別のリソースに依存しているリソースがあります。トランザクションのリストを持つ にTransaction関連付けられています。SplitTransactionトランザクションから、 のトランザクションの合計を知る必要がありSplitTransactionます。

これは私のリソースです:

.factory('Transaction', ['$resource', '$http', '$rootScope', 'SplitTransaction', '$q', function($resource, $http, $rootScope, SplitTransaction, $q){
    var Transaction = $resource('/api/v1/transaction/:id', {}, {
        query: {
            method: 'GET',
            isArray: true,
            transformResponse: tastypieDataTransformer($http).concat(function (data, headersGetter) {
                for (var idx in data) {
                    var transaction = data[idx];

                    if (transaction.installment_of) {
                        var split = transaction.installment_of.split('/');
                        var installmentId = split[split.length-1];

                        SplitTransaction.get({id: installmentId}).$promise.then(function (installment) {
                            transaction.installment_total = installment.transactions.length;
                        });
                    }
                }
                return data;
            })
        }
    });

これはhtmlです:

<tr class="transaction-row" ng-repeat="transaction in group.transactions">
    <td ng-bind="transaction.installment_total"></td>
</tr>

レンダリングされたhtmlには何も表示されません。

私は約束を使用しようとしました:

transformResponse: tastypieDataTransformer($http).concat(function (data, headersGetter) {
    for (var idx in data) {
        var transaction = data[idx];

        if (transaction.installment_of) {
            var split = transaction.installment_of.split('/');
            var installmentId = split[split.length-1];

            var deferred = $q.defer();

            SplitTransaction.get({id: installmentId}).$promise.then(function (installment) {
                var installment_total = installment.transactions.length;
                deferred.resolve(installment_total);
            });
            transaction.installment_total = deferred.promise;
        }
    }
    return data;
})

[object Object]これでバインディングは機能しているように見えますが、htmlにしか表示されません。

私は何を間違っていますか?

編集

transaction.installment_totalコールバックの外側を設定するSplitTransaction.getと、HTML に表示されるため、バインディングは問題ありません..次のように:

if (transaction.installment_of) {
    var split = transaction.installment_of.split('/');
    var installmentId = split[split.length-1];

    transaction.installment_total = 0;  // shows "0" on the html


    SplitTransaction.get({id: installmentId}, function (installment) {
        ...
    });
}

何らかの理由で、コールバック内で何が起こってもバインディングに反映されません...

一時的な解決策:

transformResponseをロードする場所からコードを削除しましたTransaction:

Transaction.query(filter).$promise.then(function (result) {                      

    $.each(result, function (idx, transaction) {                                 
        if (transaction.installment_of) {                                        
            var split = transaction.installment_of.split('/');                   
            var installmentId = split[split.length-1];                           
            transaction.installment_total = 0;                                   

            SplitTransaction.get({id: installmentId}, function (installment) {   
                transaction.installment_total = installment.transactions.length; 
            });                                                                  
        }                                                                        
    });                                                                          

    $scope.allTransactions = result;                                             
    $scope.transactionGroups = groupTransactions($scope.groupBy);                

    window.transactions = $scope.transactionGroups;                              

}).finally(function () {$scope.loading = false;});

なぜこれが機能するのかは言えません。の後にオブジェクトがコピーされて、コールバック スコープでのtransformResponse参照が役に立たなくなる可能性があります...transaction

4

1 に答える 1

0

あなたのhtmlでtransaction.installment_totalに何がバインドされているのかは明らかではありません。通常、バインドされたコントローラーの $rootScope または $scope のプロパティである可能性があり、ここにはコントローラーが表示されません。

また、明らかではありませんが、group.transactions. 空の場合、何もレンダリングされません。

しかし、何らかの方法で transaction.installment_total を html にバインドできた場合、問題は次のとおりです。

transaction.installment_total = deferred.promise;

Promsie オブジェクトを html にバインドしており、この promise の結果をバインドする必要があります。

deferred.promise.then(function(result) {
   transaction.installment_total = result;
});

これは、promise を使用する場合です。しかし、別の方法があります。

ビューに割り当てることができる ngResource のメソッド return promise と、データが利用可能になると、この promise はこのデータに置き換えられます。

これはドキュメントからのものです:

オブジェクトが空の場合、レンダリングは行われません。サーバーからデータが到着すると、オブジェクトにデータが取り込まれ、ビューが自動的に再レン​​ダリングされて新しいデータが表示されます。これは、ほとんどの場合、アクション メソッドのコールバック関数を記述する必要がないことを意味します。

言い換えれば...

var result = SplitTransaction.get({id: installmentId}, function() {
   transaction.installment_total = result.transactions.length
});

...も動作するはずです。

于 2014-01-07T00:29:39.990 に答える