简体   繁体   中英

What is the proper way to load dependencies in a controller super class of an AngularJS application?

I am building an AngularJS application that provides basic CRUD features. That app is built using TypeScript to take advantage of types and classes. I have a base controller that needs access to several AngularJS dependencies. Originally, I injected the dependencies as follows

File: base-controller.ts

class BaseController {
    private $location;
    private $routeParams;
    constructor($location, $routeParams) {
        /* Manually inject dependencies */
        this.$location = $injector.get('$location');
        this.$routeParams = $injector.get('$routeParams ');
    }
}

File: list-controller.ts

class WorkRequestListController extends BaseController {
    /* Write code to override base controller or implement local methods */
}

angular.module('app.workRequests')
    .controller('WorkRequestListController', ['$location', '$routeParams',
        ($location, $routeParams) => new WorkRequestListController($location, $routeParams)
]);

This solution works, but requires my subclass to be aware of the dependencies required by my base class. If I ever need another dependency in my base class, I would have to change every subclass and the statement which instantiates the controller. To fix these issues, I now simply pass $injector into my base class as follows:

File: base-controller.ts

class BaseController {
    private $location;
    private $routeParams;
    constructor($injector) {
        /* Load dependencies */
        this.$location = $injector.get('$location');
        this.$routeParams = $injector.get('$routeParams');
    }
}

File: list-controller.ts

class WorkRequestListController extends BaseController {
    /* Write code to override base controller or implement local methods */
}

angular.module('app.workRequests')
    .controller('WorkRequestListController', ['$injector',
        ($injector) => new WorkRequestListController($injector)
]);

Here's my question: Is this the correct way to load dependencies in a super class without forcing the subclass or other code to be aware of the dependencies?

Is this the correct way to load dependencies in a super class without forcing the subclass or other code to be aware of the dependencies?

This is a way. Angular doesn't recommend inheritance in controllers. It prefers composistion . The common functionality should go in a service / factory that gets injected into your controllers.

There's actually a really simple way to implement a base controller using the $controller service. I wrote a blog post about it recently, here's the code snippet showing how it works:

'use strict';

angular.module('Diary')

// base controller containing common functions for add/edit controllers
.controller('Diary.BaseAddEditController',
    ['$scope', 'DiaryService',
    function ($scope, DiaryService) {
        $scope.diaryEntry = {};

        $scope.saveDiaryEntry = function () {
            DiaryService.SaveDiaryEntry($scope.diaryEntry);
        };

        // add any other shared functionality here.
    }])

.controller('Diary.AddDiaryController',
    ['$scope', '$controller',
    function ($scope, $controller) {
        // instantiate base controller
        $controller('Diary.BaseAddEditController', { $scope: $scope });
    }])

.controller('Diary.EditDiaryController',
    ['$scope', '$routeParams', 'DiaryService', '$controller',
    function ($scope, $routeParams, DiaryService, $controller) {
        // instantiate base controller
        $controller('Diary.BaseAddEditController', { $scope: $scope });

        DiaryService.GetDiaryEntry($routeParams.id).success(function (data) {
            $scope.diaryEntry = data;
        });
    }]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM