AngularJS在控制器中条件注入服务的最佳实践

best practice for conditional injection of service into a controller for AngularJS

本文关键字:最佳 服务 注入 控制器 条件 AngularJS      更新时间:2023-09-26

我有一个关于angular依赖注入的问题。这个问题的终极问题是:有没有一种方法可以告诉Angular不要注入你要求的所有依赖,这样它就不会抛出错误。我想要这个功能的原因是因为我正在使用一个控制器用于常规路由(/addPlayer)和一个允许用户添加播放器的模式。也就是说,我有addplayer。html和它的控制器addplayer。js。我想让用户添加用户也通过模态。这个模式使用了addPlayer.html和addPlayer.js。然而,当使用模态时,我需要注入$modalInstance。当不使用模态,我不需要$modalInstance注入。目前我的代码给了我一个错误,当我访问'/addPlayer',因为它说它找不到$modalInstance。

更多细节:

我有一个页面(/sportsTeams,由SportsTeamsCtrl控制),其中有一个供用户选择的球员列表。其中一个选项是"—Add New Player—",当选择该选项时,将触发一个模式打开,允许用户添加一个新玩家。

我的代码看起来像这样:

首先,我有一个用于页面(/sportstreams)的控制器,用户可以在其中选择/添加球员。这个控制器有一个启动新模态的选项,它使用我在'ModalsService'中定义的一个函数。我编写ModalsService的原因是因为我希望能够从各种其他页面添加玩家,我不想一遍又一遍地编写相同的代码。

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);
           });
       }
    }
}

然后,我的'ModalsService',看起来像这样:

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;
  };
}

你可以看到,ModalsService中的'launchPlayerModal'函数调用了$modal提供的$open函数。它使用'AddPlayerCtrl'。它返回一个promise。

现在,这就是我有问题的地方。在'AddPlayerCtrl'中,我有以下代码

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);
      });
  };
} 

所以我遇到的问题是因为一个简单的原因:我想使用这个'SportsTeamCtrl'作为模态和常规路线到'/addPlayer'的控制器。基本上,当我的网站去'/addPlayer',我想使用'AddPlayerCtrl'。另外,当我有一个页面,其中有一个下拉选择列表用于选择播放器,其中一个选择将启动一个模式来添加播放器,我想使用这个相同的'AddPlayerCtrl'。

问题是,我只需要$modalInstance注入当我使用一个模态。如果我不使用模态,我不需要注入$modalInstance

目前,当我去'/addPlayer',我得到以下错误:

Error: [$injector:unpr] Unknown provider: $modalInstanceProvider <- $modalInstance

我明白为什么我得到这个错误-这是因为当我去'/addPlayer', $modal。open没有注入$modalInstance。

所以我的问题是-什么是有条件地注入$modalInstance或任何服务的最佳方式。

另外,我可能会得到很多回应说我应该有两个单独的控制器,一个用于'/addPlayer'路由,一个用于加载'addPlayer'内容的模态。我知道我可以使用控制器继承,但我不确定这是否是最好的方式。

你应该创建两个独立的控制器,并将共享逻辑推入一个服务。

然后将共享逻辑服务注入两个控制器。

$injector可以帮助您。

  • Angular $injector docs

  • 又是一篇非常好的文章