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

时间:2021-03-20 16:49:33

I am pretty new to angularjs and I want to know what is the best practice for this kind of problem. I have a function in my controller1 used for validation of registration form which is called from my uniqueField directive which is attribute:

我对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";
    };
  }
}

Now I want similar functionality in next controller too. What would be the best practice so that I dont have to redefine the function again in another controller?

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

2 个解决方案

#1


1  

Services.

Controller is not the best fit to locate this type of logic, everything that is not DOM manipulation and logic should be encapsulated into services and then this dilema is solved.

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

Lets say you have 2 controller and a function called validate:

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

Service:

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();
  }  
}]);

#2


1  

Use Scope Hierarchy

If what you mean is you want to share the whole functionality (all used scope variables) between both of the controllers, just put the functionality on a closest common ancestor scope of both scopes. The easiest way to achieve this is by applying a controller on a closest common ancestor element in the DOM hierarchy.

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

Encapsulate the Functionality and Provide a Factory

If what you mean is you need to share the functionality but have separate variables for each use, you want to encapsulate the functionality properly. You can do this by creating a factory for your validation function:

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

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

and the inject that factory into your controller and use it:

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

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

#1


1  

Services.

Controller is not the best fit to locate this type of logic, everything that is not DOM manipulation and logic should be encapsulated into services and then this dilema is solved.

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

Lets say you have 2 controller and a function called validate:

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

Service:

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();
  }  
}]);

#2


1  

Use Scope Hierarchy

If what you mean is you want to share the whole functionality (all used scope variables) between both of the controllers, just put the functionality on a closest common ancestor scope of both scopes. The easiest way to achieve this is by applying a controller on a closest common ancestor element in the DOM hierarchy.

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

Encapsulate the Functionality and Provide a Factory

If what you mean is you need to share the functionality but have separate variables for each use, you want to encapsulate the functionality properly. You can do this by creating a factory for your validation function:

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

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

and the inject that factory into your controller and use it:

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

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