简体   繁体   中英

how do i share a function between controllers?

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:

$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?

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.

Lets say you have 2 controller and a function called 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();
  }  
}]);

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM