I have a question regarding dependency injection in angular. The tldr to this question is: is there a way to tell Angular to not inject all the dependencies you asked for - so that it doesn't throw an error. The reason why I want this functionality is because I'm using a controller for both a regular route (/addPlayer) and a modal that allows users to add players. In other words, I have addPlayer.html and its controller addPlayer.js. I want to allow users to add users also through a modal. This modal uses the addPlayer.html AND the addPlayer.js. However, when using a modal, I need $modalInstance to be injected. When not using modal, I do not need $modalInstance injected. Currently my code gives me an error when I access '/addPlayer' because it says it can't find $modalInstance.
More details:
I have a page (/sportsTeams, controlled by SportsTeamsCtrl) that has a list of players for the user to select. One of the options is "--- Add New Player ---", which when selected, will trigger a modal opening, allowing the user to add a new player.
My code looks something like this:
First, I have a controller for the page (/sportsTeams) where users can select/add players. This controller has an option for launching a new modal, which uses a function that I've defined in the 'ModalsService'. The reason why I have written a ModalsService is because I want to be able to add players from various other pages, and I don't want to write the same code over and over.
App.controller('SportsTeamsCtrl', function($scope, ModalsService) {
$scope.selectOption = function(option) {
if (option == '--- Add New Player ---') {
ModalsService.launchPlayerModal().then(function(newOption) {
$scope.player = newOption;
}, function(err) {
console.log(err);
});
}
}
}
Then, my 'ModalsService', looks like so:
App.factory('ModalsService', function($modal, $q) {
var launchPlayerModal = function() {
var deferred = $q.defer();
var modalInstance = $modal.open({
templateUrl: '/partials/addPlayer.html',
controller: 'AddPlayerCtrl',
size: 'lg',
resolve: {
isModal: function() {return true;}
}
});
modalInstance.result.then(function(selectedPlayer) {
deferred.resolve(selectedPlayer);
}, function() {
deferred.reject();
console.log('modal dismissed at ' + new Date());
});
return deferred.promise;
};
}
As you can see, the 'launchPlayerModal' function in the ModalsService calls the $open function provided by $modal. It uses the 'AddPlayerCtrl'. It returns a promise.
Now, here is where I am having issues. Within 'AddPlayerCtrl', I have the following code
App.controller('AddPlayerCtrl', function($scope, isModal, $modalInstance) {
$scope.isModal = isModal;
$scope.addPlayer = function(player) {
addPlayerToDatabase(category).then(function(data) {
if ($scope.isModal) {
$modalInstance.close(data);
}
}, function(err) {
console.log(err);
});
};
}
So the issues I'm having are because of one simple reason: I'd like to use this 'SportsTeamCtrl' as a controller for modals AND regular routes to '/addPlayer'. Basically, when my site goes to '/addPlayer', I'd like to use the 'AddPlayerCtrl'. PLUS, when I have a page that has a list of drop down selections for selecting a player and one of the selections will launch a modal for adding a player, I'd like to use this SAME 'AddPlayerCtrl'.
The problem is that I ONLY need $modalInstance to be injected when I'm using a modal. If I'm not using a modal, I don't need $modalInstance to be injected.
Currently, when I go to '/addPlayer', I get the following error:
Error: [$injector:unpr] Unknown provider: $modalInstanceProvider <- $modalInstance
I understand why I'm getting this error - it's because when I go to '/addPlayer', $modal.open is not injecting $modalInstance.
So my question is this - what's the best way to conditionally inject $modalInstance or any service.
Also, I get that I may get a lot of responses saying I should just have two separate controllers, one for '/addPlayer' routes and one for modals that load 'addPlayer' content. I understand I can use controller inheritance, but I wasn't sure if this was the best way.
You should make 2 separate controllers and push the shared logic into a service.
Then injected the shared logic service into both controllers.
Hope this helps.
$injector
can help you with this.
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.