我如何在控制器之间共享功能?

时间:2014-12-11 08:58:25

标签: javascript angularjs

我对angularjs很新,我想知道这类问题的最佳做法是什么。我的controller1中有一个函数用于验证注册表单,该表单是从我的uniqueField指令中调用的,该指令属性为:

$scope.validation=function(param){
    $scope.loading[param.field]=true;

    var currentPath=$location.path(); //current route
    //function for ajax web call
    var webCall = $http({
               method: 'POST',
               url: currentPath+'/validation', 
               async : true,
               headers: {
                 'Content-Type': 'application/json'
               },
               timeout:10000,
               data: param});
    webCall.then(handleSuccess,handleError); //server call
    function handleSuccess(response) { //successful web call handler
      $scope.loaded[param.field]={};
      $scope.loading[param.field]=false;
      if(response.data.status===1) {
        $scope.loaded[param.field]["available"]=true;
        $scope.loaded[param.field]["error"]=false;
        $scope.loaded[param.field]["message"]=response.data.message;
      }
      else if(response.data.status===0){
        $scope.loaded[param.field]["available"]=false;
        $scope.loaded[param.field]["error"]=false;
        $scope.loaded[param.field]["message"]=response.data.message;
      }
    }
    function handleError(response){
      $scope.loaded[param.field]={};
      $scope.loading[param.field]=false;
      $scope.loaded[param.field]["error"]=true;
      $scope.loaded[param.field]["Message"]="Cannot fetch data from server";
    };
  }
}

现在我也希望在下一个控制器中使用类似的功能。什么是最佳实践,以便我不必再在另一个控制器中重新定义该功能?

2 个答案:

答案 0 :(得分:1)

服务。

控制器不是最适合定位这种类型的逻辑,不应该将所有不是DOM操作和逻辑的东西封装到服务中,然后解决这个困境。

假设您有2个控制器和一个名为validate的函数:

服务:

angular('mymodule').factory('validateService', function() {
    var service = {
        validate: function() {
        //validation logic
        }
    }
    return service;
});

Ctrl 1:

angular('mymodule').controller('MyCtrl1',['$scope', 'validateService', function($scope, validateService) {
  $scope.validate = function() {
      validateService.validate();
  }  
}]);

Ctrl 2:

angular('mymodule').controller('MyCtrl2',['$scope', 'validateService', function($scope, validateService) {
  $scope.validate = function() {
      validateService.validate();
  }  
}]);

答案 1 :(得分:1)

使用范围层次结构

如果您想要在两个控制器之间共享整个功能(所有使用的范围变量),那么只需将功能放在两个范围的最接近的共同祖先范围内。实现此目的的最简单方法是在DOM层次结构中最近的共同祖先元素上应用控制器。

封装功能并提供工厂

如果您的意思是需要共享功能但每次使用都有单独的变量,那么您需要正确封装功能。您可以通过为验证功能创建工厂来完成此操作:

angular.module(...).value('createSomeValidator', function () {
    return function validate (param) {
        // instead of using separate variables, use properties of this function, like:
        // validate.loading[...] = ...;
    };
});

并将工厂注入您的控制器并使用它:

angular.module(...).controller('...', ['createSomeValidator', function (createSomeValidator) {
    $scope.validateSomething = createSomeValidator();
}]);