web-dev-qa-db-fra.com

La manière correcte d'injecter une dépendance de contrôleur angular à l'intérieur d'un modal angular.ui

suivant angular.ui Modal exemple montre le modalInstance appelant un ModalIntanceCtrl qui est ensuite créé en tant que fonction:

var ModalDemoCtrl = function ($scope, $modal, $log) {

  $scope.items = ['item1', 'item2', 'item3'];

  $scope.open = function () {

    var modalInstance = $modal.open({
      templateUrl: 'myModalContent.html',
      controller: ModalInstanceCtrl,
      resolve: {
        items: function () {
          return $scope.items;
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      $scope.selected = selectedItem;
    }, function () {
      $log.info('Modal dismissed at: ' + new Date());
    });
  };
};

var ModalInstanceCtrl = function ($scope, $modalInstance, items) {

  $scope.items = items;
  $scope.selected = {
    item: $scope.items[0]
  };

  $scope.ok = function () {
    $modalInstance.close($scope.selected.item);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
};

J'ai 2 questions/problèmes:

  1. les documents recommandent de créer un contrôleur d'une autre manière (en raison de problèmes de minification), par exemple:

    myApp.controller('GreetingCtrl', ['$scope', function($scope) { $scope.greeting = 'Hola!'; }]);

Mais si je crée le contrôleur comme ça, comment pourrais-je l'injecter dans le modalInstance?

  1. Le contrôleur que j'appelle ici n'est pas un contrôleur d'instance modale mais mon loginCtrl global, est-ce un problème? dois-je sous-classer en quelque sorte le loginCtrl ou l'appeler à partir du ModalInstanceCtrl? et si oui - comment exactement?

Je serai heureux de vous guider et de clarifier cela. Merci!

34
alonisser

Votre question n'est pas très claire, mais si vous déclarez le contrôleur à l'aide de l'API du module, vous pouvez fournir le contrôleur au service modal sous forme de chaîne

myApp.controller('ModalInstanceCtrl', ['$scope', function($scope) { $scope.greeting = 'Hola!'; }]);

controller: 'ModalInstanceCtrl',

La même chose peut être faite pour loginCtrl si vous voulez l'utiliser dans le service modal.

31
Chandermani

J'ai créé ce plunker pour ceux d'entre vous comme moi qui aiment voir un exemple. Il montre comment créer un modal sans polluer l'espace de noms global. J'espère que c'est utile.

Modifié pour inclure un exemple de code selon bummi le commentaire ci-dessous

index.html

<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js">    </script>
<script src="app.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"     rel="stylesheet">
  </head>
  <body>

<div ng-controller="appController">
    <script type="text/ng-template" id="myModalContent.html">
    <div class="modal-header">
        <h3>I'm a modal!</h3>
    </div>
    <div class="modal-body">
        <span>Message:{{message}}</span>
        <ul>
            <li ng-repeat="item in items">
                <a ng-click="selected.item = item">{{ item }}</a>
            </li>
        </ul>
        Selected: <b>{{ selected.item }}</b>
    </div>
    <div class="modal-footer">
        <button class="btn btn-primary" ng-click="ok()">OK</button>
        <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
    </div>
</script>

<button class="btn btn-default" ng-click="showModal()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
  </body>
</html>

app.js

angular.module('app', ['ui.bootstrap']).
service('DataService', ['$rootScope',
  function($rootScope) {
    this.data = {};
    this.data.message = 'This is a message from a service';
    this.data.items = ['item1', 'item2', 'item3'];
  }
]).
controller('myModal', ['$scope', '$modalInstance', 'DataService',
  function($scope, $modalInstance, dataService) {
    $scope.data = dataService.data;
    $scope.message = dataService.data.message;
    $scope.items = dataService.data.items;

    $scope.selected = {
      item: $scope.items[0]
    };

    $scope.ok = function() {
      $modalInstance.close($scope.selected.item);
    };

    $scope.cancel = function() {
      $modalInstance.dismiss('cancel');
    };

  }
]).
controller('appController', ['$scope', '$modal', '$log', 'DataService',
  function($scope, $modal, $log, dataService) {

    $scope.data = dataService.data;

    $scope.showModal = function() {
      var modalInstance = $modal.open({
        templateUrl: 'myModalContent.html',
        controller: 'myModal'
      });

      modalInstance.result.then(function(selectedItem) {
        $scope.selected = selectedItem;
      }, function() {
        $log.info('Modal dismissed at: ' + new Date());
      });

    };

  }
]);
12
Mikt25

A eu un problème similaire et a déclaré le contrôleur modal sans l'ajouter au module, comme ceci:

var ModalInstanceCtrl = ['$scope', '$modalInstance', 'items', function ($scope, $modalInstance, items) { ... }

Sans aucune autre modification requise, cette syntaxe fonctionne également avec la minification.

4
Mark Meyerovich

Pour ce faire, la méthode la plus simple consiste à utiliser $ inject:

 
 // injecte le contrôleur avec les dépendances suivantes 
 ModalInstanceCtrl. $ inject = ['$ scope', '$ modalInstance', 'items']; 
 

Remplacez la méthode du contrôleur par une fonction nommée:

 
 fonction ModalInstanceCtrl ($ scope, $ modalInstance, items) {
 $ scope.items = items; 
 $ scope.selected = {
 item: $ scope.items [0] 
}; 
 
 $ scope.ok = function () {
 $ modalInstance.close ($ scope.selected. item); 
}; 
 
 $ scope.cancel = function () {
 $ modalInstance.dismiss ('cancel'); 
} ; 
}; 
 

J'ai écrit un article de blog sur ce sujet et explique comment écrire des tests pour les directives qui utilisent $ inject:

transition-angulaire-2-0-partie-2

3
Jesse Sanders