【问题标题】:Resolving resource dependency of another resource解决另一个资源的资源依赖关系
【发布时间】:2014-01-07 09:11:34
【问题描述】:

我有一个资源,其数据依赖于另一个资源。 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;
})

现在绑定似乎工作了,但它只在 html 上显示[object Object]

我做错了什么?

编辑

如果我在SplitTransaction.get 回调之外设置transaction.installment_total,它会显示在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 的引用毫无用处......

【问题讨论】:

    标签: angularjs angularjs-resource


    【解决方案1】:

    在您的 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 的方法返回promise,你可以将它分配给你的视图,当数据可用时,这个promise 将被这个数据替换。

    这是来自documentation

    一旦数据到达,空对象将导致不渲染 然后从服务器向对象填充数据和 view 会自动重新呈现自己以显示新数据。这表示 在大多数情况下,无需为 动作方法

    换句话说……

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

    ...应该也可以。

    【讨论】:

    • group.transactions 和其他绑定都很好,这是一些工作代码的 sn-p。还有其他与group.transaction 属性的绑定正在显示。如果我在SplitTransaction.get(...) 部分之前手动将total_installments 设置为某个值,则该值会显示在呈现的html 上。由于某种原因,回调中发生的更改没有反映在绑定上。
    • 顺便说一句,for 与范围混淆了,当回调命中时,transaction 值有另一个内容。但是即使改成$.each也没有解决。
    猜你喜欢
    • 2020-01-10
    • 2015-08-07
    • 2020-09-15
    • 2020-05-15
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    相关资源
    最近更新 更多