1

我正在开发一个 Angular 控制器,在负载时会发出多个异步请求。第一个请求dataAdataB. 如果第一个请求成功并且dataA被找到,并且基于它的属性我请求dataCdataD. 对于每个请求,我需要使用不同的服务(基于 的服务$http)。

对于每个请求,我应该在加载时显示一个微调器,处理请求超时的情况(并为该组件提供重试功能)以及处理找不到对象的情况。

在我当前的实现中,我正在初始化一个变量来保存状态值:

$scope.responses = {
    dataA: {
        loading: true
    },
    dataB: {
        loading: true
    },
    dataC: {
        loading: true
    },
    dataD: {
        loading: true
    }
};

我的模板中的相应示例:

<label>dataA (#{{ dataA.id }}) <i class="fa fa-spinner fa-spin" ng-show="responses.dataA.loading"></i></label>
<div ng-show="responses.dataA.success">
    <p>{{ dataA.preperty1 }} | {{ dataA.preperty2 }}</p>
</div>
<p class="error-message" ng-show="!responses.dataA.success && !loading.dataA">Failed to load dataA</p>

以及控制器的相应部分:

function loadDataA(property0) {
    BackendService.get('dataA/pr0perty0/' + property0).then(function(data) {
        $scope.dataA = data;
        $scope.responses.dataA.success = true;

        if ($scope.dataA.id) {
            loadDataC(dataA.id);
            loadDataD(dataA.id);
        }
    }, function() {
        $scope.responses.dataA.success = false;
    }).finally(function() {
        $scope.responses.dataA.loading = false;
    });
}

因此,此代码片段仅适用于dataA,其余部分我必须执行相同的操作(基本上是复制粘贴)。

我还没有添加重试功能,但它已经感觉像是可以提取的东西,并且可能以前已经实现过。

有任何想法吗?

4

1 回答 1

0

所以显然我想出了一个足够好的解决方案,一个辅助函数+一个指令。辅助函数如下:

function promiseHandler(promise, responseState, successCallback) {
    responseState.loading = true;

    promise.then(function(data) {
        successCallback(data);
        responseState.success = true;
    }, function() {
        responseState.success = false;
    }).finally(function() {
        responseState.loading = false;
    });
}

因此,loader函数可以简化如下:

promiseHandler(
BackendService.get('dataA/property0/' + property0),
$scope.responseStates.dataA,
function(data) {
    $scope.dataA = data;

    if ($scope.dataA.id) {
        loadDataC(dataA.id);
        loadDataD(dataA.id);
    }
});

我认为哪个看起来好多了。该指令如下所示:

.directive('requestSection', [function () {
    return {
        restrict: 'E',
        templateUrl: './request.section.directive.html',
        transclude: true,
        scope: {
            sectionClass: '@',
            label: '@',
            failureMessage: '@',
            responseState: '=',
            retryFunction: '&'
        },
        link: function(scope, element, attrs){
            scope.retryDefined = 'retryFunction' in attrs;
        }
    };
}]);

使用以下模板:

<div class="section {{ sectionClass }}">
    <div class="row">
        <div class="col-md-12">
            <label>{{ label }} <i class="fa fa-spinner fa-spin" ng-show="responseState.loading"></i></label>
            <div ng-hide="responseState.loading">
                <div ng-hide="responseState.success">
                    <p class="error-message">{{ failureMessage }} <a href="" ng-if="retryDefined" ng-click="retryFunction()"><i class="fa fa-refresh"></i></a></p>
                </div>
                <div ng-show="responseState.success" ng-transclude></div>
            </div>
        </div>
    </div>
</div>

这帮助我重构了大部分 HTML 代码。

欢迎任何进一步改进的想法

于 2015-12-01T21:20:06.993 回答