Freewind
Freewind

Reputation: 198188

How to reuse one controller for 2 different views?

I have defined one controller, and apply it to 2 views with small differences.

Angular code:

app.controller('MyCtrl', function($scope) {
   $scope.canSave = false;
   $scope.demo = {
      files : [{
         filename: 'aaa.html',
         source: '<div>aaa</div>'
      }, {
         filename: 'bbb.html',
         source: '<div>bbb</div>'
      }]
   }
   $scope.newFile = function(file) {
       $scope.demo.files.push(file);
   }
   $scope.$watch("demo.files", function(val) {
       $scope.canSave = true;
   }, true);
});

View 1:

<div ng-controller="MyCtrl"></div>

View 2:

<div ng-controller="MyCtrl"></div>

The sample code is very simple, but there are a lot of code and logic in my real project.

The View 1 and 2 have almost the same features, only with a few differences, but I do need to write some code for each of them in the controller.

I don't want to create 2 different controllers for them, because they have most of same logic. I don't want to move the logic to a service to share it between the 2 controllers, because the logic is not that common to be a service.

Is there any other way to do it?

Upvotes: 26

Views: 13744

Answers (4)

AgDude
AgDude

Reputation: 1185

Here is another option. Slightly modified from this blog post

app.factory('ParentCtrl',function(){
    $scope.parentVar = 'I am from the parent'
  };
});

app.controller('ChildCtrl', function($scope, $injector, ParentCtrl) {
  $injector.invoke(ParentCtrl, this, {$scope: $scope});
});

here is a plunker

Upvotes: 3

Sergey Shcherbakov
Sergey Shcherbakov

Reputation: 4778

I also faced similar problem and scope inheritance solved my problem. I wanted to "reuse" a controller to inherit common state/model ($scope) and functionality (controller functions attached to $scope) As described in the "Scope Inheritance Example" I attach parent controller to an outer DOM element and child controller to the inner. Scope and functions of parent controller "merge" seamlessly into the child one.

Upvotes: 3

axzr
axzr

Reputation: 682

I don't know your specific set-up but your 2 controllers could inherit from a common ancestor.

Type1Ctrl.prototype = new MyCtrl();
Type1Ctrl.prototype.constructor = Type1Ctrl;

function Type1Ctrl() {
  // constructor stuff goes here
}

Type1Ctrl.prototype.setScope = function() {
  // setScope
};

Type2Ctrl.prototype = new MyCtrl();
Type2Ctrl.prototype.constructor = Type2Ctrl;

function Type2Ctrl() {
  // constructor stuff goes here
}

Type2Ctrl.prototype.setScope = function() {
  // setScope
};

Upvotes: 6

Arun P Johny
Arun P Johny

Reputation: 388316

Under the given conditions I might be doing something like

function MyCommonCtrl(type){
    return function($scope, $http) {
        $scope.x = 5;

        if(type = 't1'){
            $scope.domore = function(){
            }
        }

        ....
        ....
    }
}

angular.module('ng').controller('Type1Ctrl', ['$scope', '$http', MyCommonCtrl('t1')]);
angular.module('ng').controller('Type2Ctrl', ['$scope', '$http', MyCommonCtrl('t2')]);

Then

<div ng-controller="Type1Ctrl"></div>

and

<div ng-controller="Type2Ctrl"></div>

Upvotes: 18

Related Questions