0

I have an AngularJS script (to be run on the web) and a couple of specific functions are starting to become very long, long enough that I've built a spreadsheet to generate all of the different cases, which I then simply paste into the code.

(function(){
    var app = angular
        .module('app',[])
        .controller('HostController',HostController);

    HostController.$inject = ['$scope'];
    function HostController($scope){

        var host = this;
        host.variable = "some text";

        function reallyLongFunction(a,b) {
            switch(a) {
                case "something":
                    switch(b) {};
                    break;
                case "something else":
                    switch(b) {};
                    break;
            };
        }
    }
})();

I want to move them out of the main file so that it's not cluttered with these long, generated functions while I work on the rest of the programme.

I could simply move the functions directly into another file, but they need to access variables of the type host.variable, and so need to be in the scope of the main Angular app, I believe?

How can I move these functions into a different file while retaining their access to these variables?

1
  • if your 'HostController' is registered with $stateprovider with some view then you can simply write another controller in another file and include that second controller into the same view by doing something like ng-controller"HostController_2" This way you will have the access to both of the controllers Commented Aug 3, 2018 at 12:10

2 Answers 2

2

You can move your method to separate file by creating an angular service as well. Inject that service in your controller and access the method like someSvcHelper.reallyLongFunction(a,b). This aproach will also make this method of yours as generic and will be available for other controllers as well.

But in this case you will have to pass the variables required by this function as arguments.

Sign up to request clarification or add additional context in comments.

2 Comments

He could also have a host variable in the service that he can set the value before calling the method. I think this way would be better because as he stated, he's going to have a lot of these functions.
This seems like the most angular way of going about things, but passing along all of the variables I need isn't really feasible here on account of their sheer quantity
1

Using nested ng-controller's you can have access to the other controller scope in the $scope.

angular.module('app', [])
    .controller('ctrl', function() {
      var vm = this;
      vm.value = 1;
    })
    .controller('auxCtrl', function($scope) {
      var aux = this;
      aux.result = function() {
        return $scope.vm.value + 5;
      }
    });
<div ng-app="app" ng-controller="ctrl as vm">
  <div ng-controller="auxCtrl as aux">
    <input type="number" ng-model="vm.value" /> <br/>
    {{vm.value}} <br/>
    {{aux.result()}}
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>

Edit: What if i need more than one controller?

Well, in this case i think that nested controllers will be really cumbersome, so you can try a service that has an instance of the controllers scope.

angular.module('app', [])
  .service('greeter', function() {
    const self = this;
    self.scope = {};
    self.use = scope => self.scope = scope;
    self.greet = () => 'Hello, ' + self.scope.myName;
  })
  .service('fareweller', function() {
    const self = this;
    self.scope = {};
    self.use = scope => self.scope = scope;
    self.farewell = () => 'Goodbye, ' + self.scope.myName;
  })
  .controller('ctrl', function($scope, greeter, fareweller) {
    $scope.myName = 'Lorem Ipsum';
    $scope.greeter = greeter;
    $scope.fareweller = fareweller;
    greeter.use($scope);
    fareweller.use($scope);
  });
<div ng-app="app" ng-controller="ctrl">
  <input type="text" ng-model="myName"> <br>
  {{greeter.greet()}} <br>
  {{fareweller.farewell()}} <br>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>

5 Comments

This seems super useful - is there a way for me to add, say, 4 child controllers of the parent controller without nesting each of them inside each other in a matryoshka of otherwise-unused divs? and if I did do this, for more deeply-nested controllers, would I need to use $scope.$scope.vm.value and so on?
I've made a service-based alternative, check if it solves your problem ;)
I managed to get this working! One last question, though - your variables in the controller are written as $scope.myName - I'd much prefer to use "controller as" syntax, so in my case it would be host.myName instead. Ideally, within each service, I'd then reference those using host.myName as well instead of self.scope.myName. Is that possible?
Yeah, "controller as" is the best way. In this case all you need to do is change the use method to self.use = scope => host = scope.host;, and declare the let host = {} at the beginning
Wow, that actually works - I'm amazed. You're a genius. I wish I could accept this answer again - thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.