0

using Angular JS 1.5.8 ; I have multiple controllers where we have created different methods and now when I look into 2 controllers , they have almost same methods. So mu question is how can we apply inheritance kind of thing so that both controller can get same methods from that one place.

controller A

angular.extend(vm, {
            cancel: cancel,
            change: change,
            checkTable: checkTable,
            edit: edit,
            enable: enable,
            enroll: enroll,
            listTables: listTables,
            reload: reload,
            save: save,
            show: show,
            view: view
        });

controller B

angular.extend(vm, {
            cancel: cancel,
            change: change,
            checkColumn: checkColumn,
            edit: edit,
            enable: enable,
            enroll: enroll,
            listColumns: listColumns,
            reload: reload,
            save: save,
            show: show,
            view: view
        });

As you can see both controller have multiple similar methods.

I know that we can create service but these methods already using service within.

can you suggest any good approach.

xkeshav
  • 53,360
  • 44
  • 177
  • 245
  • use controller inheritance. have a look here : http://stackoverflow.com/questions/18461263/can-an-angularjs-controller-inherit-from-another-controller-in-the-same-module – Sachet Gupta Apr 04 '17 at 06:05

3 Answers3

2

You can put all those common methods into service or factory. You can inject one service into another. So there is no issue if these methods are already using service within.

You can do it like this: app.service('service1', function(){});

app.service('service2',['service1', function(service1) {}]);

kaushlendras
  • 220
  • 1
  • 7
  • No. that is not possible as each methods using local variables of that controller and in some methods we using `$uibModal` which using different templates – xkeshav Apr 04 '17 at 06:27
  • for $uibmodal you can inject the '$uibmodal' in the service and pass modelOptions from the controller. – Amit Malik Apr 04 '17 at 07:17
1

You should use services or factory, according to John's Papa guidelines.

In fact, there is some pretty simple guidelines to respect when you are coding with Angular. I saw your verbose and notice your function are called "enable", "show" etc.. Now I don't know your code, but it seems your are manipulating DOM in the controller.

A few princples to respect in Angular :

  • Always manipulate DOM in custom directives or use the Angular directives to do it. This way, you now the only thing manipulating DOM is either your CSS or your directives, and it takes the role of a thin layer : very easy if you want to find something that fucked up your DOM.

  • You should put the least amount of logic into your controllers. It allow you to re-use the logic in other controllers, but also to test your code more easily, and it also keep the controllers simple and very easy to understand with a simple glance.

  • Always use services to get the data, the controller should only be focused on the view, and only know where and what to ask for and when, but should not care about implementation details.

Now I saw your comments and you complained that each function uses local variables from the controller.

A statement to begin : If you are using a global variable in a controller which is not associated to the view model (accessible to the view), then you should be able to optimize it.

Then if you have to manipulate local data from the controller, and it's understandable, simply put them as arguments in the function call. If you want to modify them, then you could use a callback function.

Here's an example :

var vm = this;

// bad way
function enroll(){
// your current function modifying vm.example1 and vm.example2
}

//good way
function enroll(){
   serviceName.enroll(vm.example1, vm.example2, function(value1, value2){
    vm.example1 = value1;
    vm.example2 = value2;
   }
}

Hope this can help, and I advise you yo read the entier guideline, it really helped me learning a lot of things about this framework.

Alburkerk
  • 1,564
  • 13
  • 19
  • Thank you for the reply. Sure I will look into that guidelines. I am using `.service` wherever my controller using CRUD operations and need `$http` service. – xkeshav Apr 04 '17 at 12:17
0

You can use javascript inheritance to achieve it.

    function controllerBase() {}

    controllerBase.prototype = {
      cancel: cancel,
      change: change,
      checkColumn: checkColumn,
      edit: edit,
      enable: enable,
      enroll: enroll,
      listColumns: listColumns,
      reload: reload,
      save: save,
      show: show,
      view: view
    };


    function controllerA() {
      var vm = this;
    }

    controllerA.prototype = Object.create(controllerBase.prototype);

    function controllerB() {
      var vm = this;
    }

    controllerB.prototype = Object.create(controllerBase.prototype);


    angular.module('app', [])
      .controller('controllerA', controllerA)
      .controller('controllerB', controllerB);
ajai Jothi
  • 2,284
  • 1
  • 8
  • 16
  • I believe that's right direction. But what you would do if controllerA and controllerB are in different files and/or modules? Usually we don't have the app as one file with 10k lines. – Estus Flask Apr 04 '17 at 10:52