0

我有一个资源,其数据依赖于另一个资源。TransactionSplitTransaction具有交易列表的 a 相关联。从交易中,我需要知道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,并且您需要绑定此承诺的结果:

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

那就是如果你想使用承诺。但还有另一种方式。

ngResource 的方法返回 Promise,您可以将其分配给您的视图,当数据可用时,此 Promise 将被此数据替换。

这是来自文档

拥有一个空对象不会导致渲染,一旦数据从服务器到达,那么该对象就会被数据填充,并且视图会自动重新渲染自身以显示新数据。这意味着在大多数情况下,我们不必为操作方法编写回调函数

换句话说...

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

......也应该工作。

于 2014-01-07T00:29:39.990 回答