Comment passer des paramètres à un modal?


96

Je veux passer le userNamed'une liste de userNameclics d'utilisateurs connectés sa à Twitter bootstrap modal. J'utilise des grails avec angularjs , où les données sont rendues via angularjs .

Configuration

Ma page de vue Grails encouragement.gspest

<div ng-controller="EncouragementController">
    <g:render template="encourage/encouragement_modal" />
    <tr ng-cloak
                  ng-repeat="user in result.users">
                   <td>{{user.userName}}</rd>
                   <td>
                      <a class="btn btn-primary span11" href="#encouragementModal" data-toggle="modal">
                            Encourage
                       </a>
                  </td>
                </tr>

Mon encourage/_encouragement_modal.gspest

<div id="encouragementModal" class="modal hide fade">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"
      aria-hidden="true">&times;</button>
    <h3>Confirm encouragement?</h3>
  </div>
  <div class="modal-body">
      Do you really want to encourage <b>{{aModel.userName}}</b>?
  </div>
  <div class="modal-footer">
    <button class="btn btn-info"
      ng-click="encourage('${createLink(uri: '/encourage/')}',{{aModel.userName}})">
      Confirm
    </button>
    <button class="btn" data-dismiss="modal" aria-hidden="true">Never Mind</button>
  </div>
</div>

Alors, comment puis-je passer userNameà encouragementModal?


1
Vous devez gérer ces choses en utilisant angularjs. checkout ng-inclure.
zs2020

Réponses:


149

Pour passer le paramètre, vous devez utiliser la résolution et injecter les éléments dans le contrôleur

$scope.Edit = function (Id) {
   var modalInstance = $modal.open({
      templateUrl: '/app/views/admin/addeditphone.html',
      controller: 'EditCtrl',
      resolve: {
         editId: function () {
           return Id;
         }
       }
    });
}

Maintenant, si vous allez utiliser comme ceci:

app.controller('EditCtrl', ['$scope', '$location'
       , function ($scope, $location, editId)

dans ce cas, editId ne sera pas défini. Vous devez l'injecter, comme ceci:

app.controller('EditCtrl', ['$scope', '$location', 'editId'
     , function ($scope, $location, editId)

Maintenant, cela fonctionnera bien, je suis confronté au même problème plusieurs fois, une fois injecté, tout commence à fonctionner!


Comme tout Angular, l'injection est la solution. Merci!
Sebastialonso

cette erreur indéfinie me faisait la tête jusqu'à ce que je vois votre réponse! Fonctionne comme un charme!
Dan

Comment faire si, au lieu d'un simple var, vous voulez passer un objet timeout? la résolution ne se déclenchera pas tant que le délai d'expiration n'aura pas été résolu, ce qui se produit à la fin du délai d'attente
Danny22

La chose qui me manquait dans ma solution était d'utiliser $ scope et $ location entre de simples guillemets .... Je ne savais pas que ces arguments devaient être des chaînes
rshimoda

1
En faisant cela, j'obtiens "angular.js: 10071 Erreur: [$ injector: un] Fournisseur inconnu: editIdProvider <- editId". Des idées?
Oskar Lund

57

L'autre ne fonctionne pas. Selon la documentation, c'est ainsi que vous devez le faire.

angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal) {

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

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

  $scope.test = test;
};

Voir plunkr


1
Vous ne devriez pas encapsuler ceci comme ['$ scope', '$ modalInstance', function () pour injecter des dépendances?
joseramonc

1
Merci pour le commentaire, Jose, c'était exactement mon problème. Si vous réduisez votre code Angular, oui, vous devez utiliser la syntaxe de tableau pour ModalInstanceCtrl.
mcole

Jose, +1 C'était aussi mon problème. Et je pense à tout le monde utilisant AngularUI!
Matteo Defanti

50

Vous pouvez également créer une nouvelle étendue et passer les paramètres via l'option scope

var scope = $rootScope.$new();
 scope.params = {editId: $scope.editId};
    $modal.open({
        scope: scope,
        templateUrl: 'template.html',
        controller: 'Controller',
    });

Dans votre passe de contrôleur modal dans $ scope, vous n'avez alors pas besoin de transmettre et itemsProvider ou ce que vous avez résolu

modalController = function($scope) {
    console.log($scope.params)
}

2
$ rootScope. $ new (); <=== ceci devrait être voté pour. truc très soigné. Merci!
reflog

3
+1 Puisque cela permet de transmettre des données sans avoir à définir un contrôleur pour le modal. BTW, vous pouvez simplement $scope.$new(true)créer une nouvelle portée isolée sans avoir besoin d'injecter $rootScope.
Santosh

@Mwayi: Merci pour cette astuce! Le problème avec l'injection classique (utilisation resolve) est que les arguments sont obligatoires, donc à chaque fois que vous ouvrez un modal, vous devez résoudre tous les arguments ou l'appel à $modal.open()échouera car le contrôleur veut ses arguments. En utilisant cette scopeastuce, les dépendances deviennent facultatives.
stackular

23

Vous pouvez également facilement passer des paramètres au contrôleur modal en ajoutant une nouvelle propriété avec une instance de modal et en l'obtenir au contrôleur modal. Par exemple:

Voici mon événement de clic sur lequel je veux ouvrir la vue modale.

 $scope.openMyModalView = function() {
            var modalInstance = $modal.open({
                    templateUrl: 'app/userDetailView.html',
                    controller: 'UserDetailCtrl as userDetail'
                });
                // add your parameter with modal instance
                modalInstance.userName = 'xyz';
        };

Contrôleur modal:

angular.module('myApp').controller('UserDetailCtrl', ['$modalInstance',
                function ($modalInstance) {
                    // get your parameter from modal instance
                    var currentUser = $modalInstance.userName;
                    // do your work...
                }]);

Exactement ce dont j'avais besoin. A parfaitement fonctionné.
theFish

17

J'ai essayé comme ci-dessous.

J'ai appelé le ng-clickcontrôleur angularjs sur le bouton Encourager ,

               <tr ng-cloak
                  ng-repeat="user in result.users">
                   <td>{{user.userName}}</rd>
                   <td>
                      <a class="btn btn-primary span11" ng-click="setUsername({{user.userName}})" href="#encouragementModal" data-toggle="modal">
                            Encourage
                       </a>
                  </td>
                </tr>

J'ai mis userNamedu encouragementModalcontrôleur angularjs.

    /**
     * Encouragement controller for AngularJS
     * 
     * @param $scope
     * @param $http
     * @param encouragementService
     */
    function EncouragementController($scope, $http, encouragementService) {
      /**
       * set invoice number
       */
      $scope.setUsername = function (username) {
            $scope.userName = username;
      };
     }
    EncouragementController.$inject = [ '$scope', '$http', 'encouragementService' ];

J'ai fourni un endroit ( userName) pour obtenir la valeur du contrôleur angularjs encouragementModal.

<div id="encouragementModal" class="modal hide fade">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"
      aria-hidden="true">&times;</button>
    <h3>Confirm encouragement?</h3>
  </div>
  <div class="modal-body">
      Do you really want to encourage <b>{{userName}}</b>?
  </div>
  <div class="modal-footer">
    <button class="btn btn-info"
      ng-click="encourage('${createLink(uri: '/encourage/')}',{{userName}})">
      Confirm
    </button>
    <button class="btn" data-dismiss="modal" aria-hidden="true">Never Mind</button>
  </div>
</div>

Cela a fonctionné et je me suis salué.


3
Je +1 et je vous salue. Si quelqu'un a besoin de passer l'utilisateur entier au modal plutôt qu'à une seule chaîne pour son nom, dans le contrôleur, n'oubliez pas d'utiliser angular.copy(user).
youri

10

Vous devriez vraiment utiliser Angular UI pour ces besoins. Vérifiez-le: boîte de dialogue de l'interface utilisateur angulaire

En un mot, avec la boîte de dialogue Angular UI, vous pouvez passer une variable d'un contrôleur au contrôleur de dialogue à l'aide de resolve. Voici votre contrôleur "de":

var d = $dialog.dialog({
  backdrop: true,
  keyboard: true,
  backdropClick: true,
  templateUrl:  '<url_of_your_template>',
  controller: 'MyDialogCtrl',
  // Interesting stuff here.
  resolve: {
    username: 'foo'
  }
});

d.open();

Et dans votre contrôleur de dialogue:

angular.module('mymodule')
  .controller('MyDialogCtrl', function ($scope, username) {
  // Here, username is 'foo'
  $scope.username = username;
}

EDIT: Depuis la nouvelle version de l'interface utilisateur, l'entrée de résolution devient:

resolve: { username: function () { return 'foo'; } }


Salut, je n'ai pas essayé de cette façon. Mais +1 pour une suggestion.
prieragupd

3
en fait, cela devrait êtreresolve: function(){return {username: 'foo'}}
SET

La réponse SET ne fonctionnera pas. le vélo l'a juste en dessous, il devrait être - résoudre: {data: function () {return 'foo';}}
bornytm

1
@bornytm Aujourd'hui, vous avez raison. Mais quand ma réponse a été écrite, la syntaxe était:resolve: { username: 'foo'}
Sandro Munda

4

Vous pouvez simplement créer une fonction de contrôleur et passer vos paramètres avec l'objet $ scope.

$scope.Edit = function (modalParam) {
var modalInstance = $modal.open({
      templateUrl: '/app/views/admin/addeditphone.html',
      controller: function($scope) {
        $scope.modalParam = modalParam;
      }
    });
}

1

Si vous n'utilisez pas AngularJS UI Bootstrap, voici comment je l'ai fait.

J'ai créé une directive qui contiendra tout cet élément de votre modal et recompiler l'élément pour y injecter votre portée.

angular.module('yourApp', []).
directive('myModal',
       ['$rootScope','$log','$compile',
function($rootScope,  $log,  $compile) {
    var _scope = null;
    var _element = null;
    var _onModalShow = function(event) {
        _element.after($compile(event.target)(_scope));
    };

    return {
        link: function(scope, element, attributes) {
            _scope = scope;
            _element = element;
            $(element).on('show.bs.modal',_onModalShow);
        }
    };
}]);

Je suppose que votre modèle modal est dans la portée de votre contrôleur, puis ajoutez la directive my-modal à votre modèle. Si vous avez enregistré l'utilisateur cliqué dans $ scope.aModel , le modèle d'origine fonctionnera désormais.

Remarque: la portée entière est maintenant visible pour votre modal, vous pouvez donc également y accéder à $ scope.users .

<div my-modal id="encouragementModal" class="modal hide fade">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"
      aria-hidden="true">&times;</button>
    <h3>Confirm encouragement?</h3>
  </div>
  <div class="modal-body">
      Do you really want to encourage <b>{{aModel.userName}}</b>?
  </div>
  <div class="modal-footer">
    <button class="btn btn-info"
      ng-click="encourage('${createLink(uri: '/encourage/')}',{{aModel.userName}})">
      Confirm
    </button>
    <button class="btn" data-dismiss="modal" aria-hidden="true">Never Mind</button>
  </div>
</div>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.