0

I have a project where a lot of the models are going to be managed by almost the same controller-code with the only exception that they are calling different services.

The way I'm handling this now is by instantiating a Crud-Controller with common code into every custom controller and then redirecting the service-call by changing the variable inside the custom controller. I.e. vm.service.get() inside the Crud-Controller changes by setting vm.service = teamService; in a custom controller.

This is how I instantiate the Crud-Controller into my custom controllers at the moment:

$injector.invoke(Crud, this, {$scope:$scope});

This works fine, however I don't know if this is the right way to share common controller code. Maybe it is possible to instantiate a service for this use? Because the question I have (if my way of doing it is correct), how do I access other controllers while using IIFE? Right now I am not using IIFE since I have not figured out a way to do so.

I have tried with angular.module('app').controller('Crud') but it does not work.

I.e: How do I get access to the PrimaryCtrl's edit function without using $injector or relying on the $scope inheritance? http://jsfiddle.net/tcVhN/62/

6
  • Please, provide the code that explains the statements, a couple of lines isn't enough. Commented Jul 14, 2015 at 9:42
  • I.e: How do I get access to the PrimaryCtrl's edit function without using $injector or relying on the $scope inheritance? jsfiddle.net/tcVhN/50 Commented Jul 15, 2015 at 9:25
  • your service doesn't make sense. in fetchUsers, for example, you are checking if users exists, and if it is, you are rejecting the promise with an error, which means if users was in the cache already, you aren't returning anything. Commented Jul 15, 2015 at 9:34
  • @user2624679 I see. This is the primary reason why controllerAs is there. Dismiss $scope for everything except scope $* stuff, use this instead and extend controllers with JS from common function or class. Commented Jul 15, 2015 at 10:01
  • @Claies Sorry. I used an old link. Correct one: jsfiddle.net/tcVhN/62 Commented Jul 15, 2015 at 14:14

1 Answer 1

0

It looks like your example uses Angular 1.0.x that supports global controllers out of the box. That's how it would be done with more recent Angular, without going too deep into the perils of JS inheritance.

'use strict';

(function (root, angular) {
    root.ctrls = root.ctrls || {};

    var primaryCtrl = function ($scope) {
        var self = this;
        console.log('primaryCtrl constructor', self, $scope);
    };
    primaryCtrl.prototype = {
        items: ['Item 1', 'Item 2'],
        edit: function (item) {
            //do stuff
        }
    };
    primaryCtrl.$inject = ['$scope'];

    root.ctrls.primaryCtrl = primaryCtrl;
})(this, angular);

(function (root, angular) {
    root.ctrls = root.ctrls || {};

    var secondaryCtrl = function ($scope) {
        var self = this;
        console.log('secondaryCtrl constructor', self, $scope);
    };
    secondaryCtrl.prototype = angular.extend({},
        root.ctrls.primaryCtrl.prototype,
        {
            items: ['Stuff 1', 'Stuff 2']
        }
    );
    secondaryCtrl.$inject = ['$scope'];

    root.ctrls.secondaryCtrl = secondaryCtrl;
})(this, angular);

var app = angular.module('app',[]);
app.controller('PrimaryCtrl', ctrls.primaryCtrl);
app.controller('SecondaryCtrl', ctrls.secondaryCtrl);

and

<div ng-controller="PrimaryCtrl as primary">
    <p ng-repeat="item in primary.items">{{item}}</p>
</div>

<div ng-controller="SecondaryCtrl as secondary">
    <p ng-repeat="item in secondary.items">{{item}}</p>
</div>

You may also check Angular Classy, which brings opinionated but viable extending syntax to Angular.

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

4 Comments

Thanks for your answer. How would I be able to access the primary controller if the controllers are separated in different files with IIFE?
Your best bet is to require it with build system of your choice or es6 modules. Otherwise you will have to export globals from IIFE to window like it is usually done, (function (root) { var ctrl = ...; root.ctrl = ctrl; })(this);. Keep in mind that you can always separate common methods into service and mixin them in controllers like angular.extend(this, baseCtrlService), but managing dependencies by means of Angular in a big app like that will make the one shoot into his foot most times.
Thanks again. So how would you solve this "problem" where you have a lot of common controller code that you want to share? Would you say that DRY is mandatory here or could you just have 3-5 very similar controllers?
I guess you're already following 'thin controllers, fat services' principle, so there are no logic in controllers, only scope bindings. It depends on the amount of WET code, I would personally leave them as is or go ES6/TS classes for long-term project.

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.