1

I'm using angular route and I have a situation, where two views basically manipulate the same data. Now, the data is provided via factory to both controllers. However, the functionalities are quite the same.

I won’t go into too many details, but creating a service or factory (which is commonly suggested in this situations) does not solve my issues, since the button clicks etc. are basically the same in both views. I'd still have to define the same button clicks twice, except the logic would be in the factory. The only difference between my two views is, that view2 has a few more functionalities than view1, otherwise it’s basically the same.

What I’d need now is some kind of controller inheritance. I found a couple of solutions, but I’m still searching for an optimal and correct solution. I used the angular.extend to clone the scope, but I’m not sure if this is the correct way.

Furthermore, what happens with $scope from view1 when it gets cloned to $scope in view2? Does it get overridden?

Here’s a simple example: http://jsbin.com/fiqeha/1/edit?html,js,output

1
  • Can't you use the same controller for both views? Otherwise you would have troubles injecting services/factories into both controllers. Commented Dec 19, 2014 at 12:50

2 Answers 2

4

You can implement controller inheritance by declaring the base as a factory and injecting them into your controllers using $injector e.g.

angular.module('app').factory('BaseController', function () {

  var controller= function($scope){

    $scope.value = 0;

    $scope.testFunction = function () {
      $scope.value++;
    }; 

    $scope.overrideFunction = function() {
       $scope.value--;
    }
  }

  return controller;
});

and in the child controller,

angular.module('app').controller('ChildController', function ($scope, 
  $injector, BaseController) {

  //Inherit base controller - first line in controller
  $injector.invoke(BaseController, this, {$scope: $scope});

  $scope.overrideFunction = function () {
     //call base function
     $scope.value = $scope.testFunction() + 2;
  };

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

Comments

0

Why not use the same controller? You will get two separate instances of the controller, which should be exactly what you want.

Here is a fork of your jsbin.

js:

angular.module('app', []).
controller('ctrl1', ['$scope', function($scope){

    $scope.name = "John";

    $scope.displayName = function(){
        alert($scope.name);
    };

    $scope.getNameLength = function(){
        alert($scope.name.length);
    };

}]);

html:

<body>
    <b>view1.html</b>
    <div ng-controller="ctrl1">
        <input ng-model="name" />
        <button ng-click="displayName()">Display</button>
    </div>
    <br />
    <br />
    <b>view2.html</b>
    <div ng-controller="ctrl1">
        <input ng-model="name" />
        <button ng-click="displayName()">Display</button>
        <button ng-click="getNameLength()">Length</button>
    </div>
</body>

4 Comments

Yeah that was my initial solution as well, but then it got really messy, because view2 had at least five specific methods. And there's no need to include view1 as well. Is my example wrong?
It is up do you, but have 5 extra methods would be a compelling reason to try some sort of inheritance. Either make 2 different controllers and copy some methods (move the complex logic to services), or have the same controller with 2 instances.
Thank you for your response. I'm still struggling to understand why the example in original post might not be a good solution or if I'm breaking any rules of angular by copying scope from one controller?
You are not breaking any rules per se. But, it is unconventional and developers would struggle to immediately see why you are doing an extend. Better to keep in simple perhaps.

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.