如何将功能外包给工厂/服务

时间:2014-03-29 23:28:46

标签: angularjs

我对如何将多个控制器中使用的功能“外包”到工厂或服务中感到困惑。

该函数检查来自WebAPI的响应中的错误消息

function errorLog(error) {
    // empty old validation errors
    $scope.validationErrors.length = 0;
    // get new validation errors 
    var obj = error.data.ModelState;
    for (var key in obj) {
         $scope.validationErrors.push(obj[key]);
    }
}

并将它们推送到变量“validationErrors”,我用它来显示它们:

<div ng-repeat="err in validationErrors">
      {{err.toString()}}
</div>

该函数在$ resource-Posts的错误函数中调用,并获取原始“错误”。我不想在每个控制器中重复该功能。我想将它放在一个地方,但仍然能够将错误推送到每个控制器中定义的“本地”变量validationErrors。

我很乐意向正确的方向暗示。这是使用服务或工厂甚至其他概念的情况吗?

2 个答案:

答案 0 :(得分:1)

您的服务只是作为可以注入控制器的通用状态。如果您在服务中公开说出validationErrors对象,则只需将其绑定到任何本地控制器范围,并且任何更新都应传播到使用它的所有控制器。这应该让你开始:

http://jsfiddle.net/HB7LU/2863/

服务/控制器代码:

myApp.factory('errorService', function() {
    var cont = { validationErrors: [] };

    return {
        getErrorList: function() { return cont; }
    }
});

function MyCtrl($scope, errorService) {
    $scope.es = errorService.getErrorList();    

    $scope.es.validationErrors.push('Some error');
}

function MyOtherCtrl($scope, errorService) {
    $scope.es = errorService.getErrorList();   

    $scope.es.validationErrors.push('Some other error');
}

查看(使用相同服务的2个视图):

<div ng-controller="MyCtrl">
    <div ng-repeat="err in es.validationErrors">{{err}}</div>
</div>
<div ng-controller="MyOtherCtrl">
    <div ng-repeat="err in es.validationErrors">{{err}}</div>
</div>

编辑:

在下面的评论之后,我意识到你只是想创建一个可重用的功能,而不是必须保持控制器之间的共同状态。在这种情况下,请将$scope传递到服务中的公共功能。

myApp.factory('errorService', function() {
    return {
        errorLog: function(scope, error) {
            // empty old validation errors
            scope.validationErrors.length = 0;
            // get new validation errors 
            var obj = error.data.ModelState;
            for (var key in obj) {
                scope.validationErrors.push(obj[key]);
            }
        }
    }
}

然后在任何控制器内部注入errorService,并简单地传递POST结果以及控制器范围,例如:

errorService.errorLog($scope, postError);

此外,在您的情况下,您并不需要将范围根目录传递到服务中。你可以直接传递$scope.validationErrors。一切都取决于你想要的。

答案 1 :(得分:1)

解决方案可能是实现响应拦截器并捕获那里的错误。由于您希望有多个独立的验证错误部分,因此您需要了解如何识别错误所属的部分。

然后创建一个指令(示例列表验证),它将显示之前捕获的错误。您可以使用公共服务在响应拦截器之间共享错误,也可以让拦截器广播指令将收到的错误。

关键是每个指令都应该是可配置的,只显示特定键的错误,响应拦截器必须识别生成错误的键。