2

Suppose I have two different view controllers, whereas both use the same function within their scopes, e.g. set some scope variable, something like this:

View1Cntr.js

app.controller('View1Cntr', ['$scope', function($scope) {

    $scope.coloredContent = [];  // default

    // View1Cntr custom code here

    $scope.clearColoredContent = function() {
        $scope.coloredContent = [];
    }

}]);

View2Cntr.js

app.controller('View2Cntr', ['$scope', function($scope) {

    $scope.coloredContent = [];  // default

    // View2Cntr custom code here

    $scope.clearColoredContent = function() {
        $scope.coloredContent = [];
    }

}]);

Is there any way I could only define the function once and pass it to both controllers, so that the maintenance becomes easier?

I guess, this is a closure case (please, correct me if I am wrong) and that is why I am not sure how to get around it.

Thanks!

Kenny Eng
  • 149
  • 10
jazzblue
  • 2,411
  • 4
  • 38
  • 63
  • yes, you could create `factory`, with some method, like `clearColoredContent` inject this factory in both controller, and pass needed scope, to this – Grundy Feb 12 '16 at 19:04
  • @Grundy: My function sets a free variable which is a $scope variable. I am not sure how I can share such a function through a service. Could you, please, provide an example? Thanks! – jazzblue Feb 12 '16 at 19:32

4 Answers4

3

you could create factory, with some method, like clearColoredContent inject this factory in both controller, and pass needed scope, to this.

app.factory('Utility', function(){
    return {
        clearColoredContent: function(scope){
            scope.coloredContent = [];
        }
    }
})

and use it like this

app.controller('View2Cntr', ['$scope','Utility' , function($scope,Utility) {

    $scope.coloredContent = [];  // default

    // View2Cntr custom code here

    $scope.clearColoredContent = function() {
        Utility.clearColoredContent($scope);
    }

}]);

Or you can use inside Utility function this, and simple assign this utility function to $scope

app.factory('Utility', function(){
    return {
        clearColoredContent: function(){
            this.coloredContent = [];
        }
    }
})

app.controller('View2Cntr', ['$scope','Utility' , function($scope,Utility) {

    $scope.coloredContent = [];  // default

    // View2Cntr custom code here

    $scope.clearColoredContent = Utility.clearColoredContent;

}]);
Grundy
  • 13,356
  • 3
  • 35
  • 55
  • could 'this.coloredContent' in factory really be able to access the scope variable in the controller? When i console.log 'this' variable, it shows the factory content, instead of the controller... did i miss out sth? – zeroflaw Dec 31 '19 at 01:24
  • @zeroflaw, seems i miss this line: `$scope.clearColoredContent = Utility.clearColoredContent;` – Grundy Dec 31 '19 at 16:21
2

First you will have to create a factory:

app.factory('testFactory', function(){
    return {
        clearColoredContent: function(coloredContent) {
            coloredContent = [];
            return coloredContent;
        }
    }               
});

And then in the controller include the factory and use it:

app.controller('View1Cntr', ['$scope', 'testFactory' function($scope, testFactory) {

    $scope.coloredContent = [];  // default

    // View1Cntr custom code here

    $scope.clearColoredContent = testFactory.clearColoredContent($scope.coloredContent);
}]);
Sarantis Tofas
  • 5,097
  • 1
  • 23
  • 36
  • Thanks, that would work for the case I described. I did simplify my case. Normally I need to modify multiple $scope variables. Of course, I could construct an object consisting of multiple values and use your method. However, I was curious if I could do it in a nicer way or whether this is the only way. Thanks anyway, a point to you! – jazzblue Feb 12 '16 at 19:40
0

One way you could use the function in both controllers is to define the function in the parent controller so it will be available in both child controllers. If you have not defined the parent controller, you can define it on html element.

HTML

<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js"></script>
<script src="app.js"></script>
<title>Angular JS Demo</title>
</head>
<body ng-controller="parent">
  <div ng-controller="child1"> {{ child1Number }} </div>
  <div ng-controller="child2"> {{ child2Number }} </div>
</body>
</html>

JS

angular.module('app', []).controller('parent', function($scope) {
    $scope.plus = function(input) {
        return input + 1;
    }
}).controller('child1', function($scope) {
    $scope.child1Number = $scope.$parent.plus(1);
}).controller('child2', function($scope) {
    $scope.child2Number = $scope.$parent.plus(2);
});
Farzad Yousefzadeh
  • 2,461
  • 1
  • 20
  • 27
0

Yes, this can be done by defining the function in a service or factory and then using that in your controller. Whether you use a service or factory depends on what you're trying to do but some good guidance is here https://stackoverflow.com/a/15666049/5919154

Community
  • 1
  • 1
nathan.medz
  • 1,595
  • 11
  • 21
  • My function sets a free variable which is a $scope variable. I am not sure how I can share such a function through a service. Could you, please, provide an example? Thanks – jazzblue Feb 12 '16 at 19:29