Reputation: 924
I want to use a base AngularJS controller for multiple very similar views, but I want to change the Resource
that is passed into each controller.
Here is the base controller:
coreAppControllers.controller('ModalEditCtrl',
function ($scope, $stateParams, Resource, $state, $modalInstance) {
// A bunch of methods calling Resource
}
);
Now I want to use this controller in another controller, but using a Resource
specific to the parent controller.
coreAppControllers.controller('MachinesEditCtrl', ['$modal',
function ($modal) {
$modal.open({
backdrop: 'static',
keyboard: false,
templateUrl: '/partials/v1/resources/machines/edit',
controller: //ModalEditCtrl with specific Machine resource injected
});
}]
);
This is possibly the wrong way to go about this in JavaScript. In other languages I would extend a base class, but I'm not certain what that would be in a prototypical language.
Thank you to PSL for the answer, however that method failed to inject the $modalInstance
correctly. The eventual solution was to use the resolve attribute, and let DI worry about the rest.
For some reason you must wrap the service in an anonymous function when passing into resolve.
coreAppControllers.controller('MachinesEditCtrl', ['$modal', 'MachinesAPI',
function ($modal, MachinesAPI) {
$modal.open({
backdrop: 'static',
keyboard: false,
templateUrl: '/partials/v1/resources/machines/edit',
controller: 'ModalEditCtrl',
resolve: {
Resource: function () {
return MachinesAPI;
}
}
});
}
]);
Upvotes: 2
Views: 139
Reputation: 123739
I think your concern is more on the DI side, you could easily do it this way:-
Say this is your controller:-
function ModalEditCtrl($scope, $stateParams, Resource, $state, $modalInstance) {
// A bunch of methods calling Resource
}
app.controller('ModalEditCtrl',['$scope', '$stateParams', 'Resource', '$state', $modalInstance, ModalEditCtrl]);
Just register your specific controller as well:-
app.controller('ModalEditCtrlParent1',['$scope', '$stateParams', 'OtherResource', '$state', $modalInstance, ModalEditCtrl]);
app.controller('ModalEditCtrlParent2',['$scope', '$stateParams', 'SomeOtherResource', '$state', $modalInstance, ModalEditCtrl]);
and in your modal just do:-
$modal.open({
backdrop: 'static',
keyboard: false,
templateUrl: '/partials/v1/resources/machines/edit',
controller: 'ModalEditCtrlParent1'
});
This way you keep your controller follow OCP and any new view you just have to add a new one instead of modifying the existing one.
Here is another way you could do it using $controller
service to get the instance of a controller based on the Dependencies that you provide:-
coreAppControllers.controller('MachinesEditCtrl', ['$modal', 'Resource2' function ($modal, Resource) {
var viewModel = $scope.$new(true);
$modal.open({
backdrop: 'static',
keyboard: false,
scope: viewModel,
templateUrl: '/partials/v1/resources/machines/edit',
controller: function(){
return $controller('ModalEditCtrl', {$scope:viewModel, Resource:Resource});
}
});
}]
);
And well you can use any syntactic sugar for prototypical inheritance (I use typescript so i generally do extends), but it depends upon what are you trying to extend? is the scope ($scope) or the controller (controller As) itself (You basically are going to extend the view model).
Upvotes: 1