有条件地将服务注入AngularJS控制器的最佳实践

时间:2014-07-10 04:52:44

标签: javascript angularjs

我有一个关于角度依赖注入的问题。这个问题的问题是:有没有办法告诉Angular不要注入你要求的所有依赖项 - 这样就不会抛出错误。我想要这个功能的原因是因为我正在使用常规路径(/ addPlayer)的控制器和允许用户添加玩家的模态。换句话说,我有addPlayer.html及其控制器addPlayer.js。 我想允许用户也通过模式添加用户。此模式使用addPlayer.html和addPlayer.js。但是,当使用模态时,我需要注入$ modalInstance。当不使用模态时,我不需要注入$ modalInstance。目前我的代码在访问'/ addPlayer'时给出了一个错误,因为它说它无法找到$ modalInstance。

更多详情:

我有一个页面(/ sportsTeams,由SportsTeamsCtrl控制),其中包含供用户选择的播放器列表。其中一个选项是“---添加新玩家---”,选中后会触发模态打开,允许用户添加新玩家。

我的代码看起来像这样:

首先,我有一个页面控制器(/ sportsTeams),用户可以在其中选择/添加玩家。该控制器有一个启动新模态的选项,它使用我在'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'。它会返回一个承诺。

现在,我遇到了问题。在'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'内容的模态。我知道我可以使用控制器继承,但我不确定这是否是最佳方式。

2 个答案:

答案 0 :(得分:2)

您应该创建2个独立的控制器并将共享逻辑推送到服务中。

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

希望这有帮助。

答案 1 :(得分:1)

$injector可以为您提供帮助。