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?

prier
la source
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!

Ali Adravi
la source
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

vélo
la source
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)
}
Mwayi
la source
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...
                }]);
Rubi saini
la source
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é.

prier
la source
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'; } }

Sandro Munda
la source
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;
      }
    });
}
itay oded
la source
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>
élite
la source