Come passare i parametri a un modale?


96

Voglio passare il userNameda un elenco di userNamesa che l'utente ha effettuato l'accesso al bootstrap di Twitter modal. Sto usando graal con angularjs , dove i dati vengono resi tramite angularjs .

Configurazione

La mia pagina di visualizzazione dei Graal encouragement.gspè

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

Il mio encourage/_encouragement_modal.gspè

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

Allora, come posso passare userNamea encouragementModal?


1
Dovresti gestire queste cose usando angularjs. checkout ng-include.
zs2020

Risposte:


149

Per passare il parametro è necessario utilizzare la risoluzione e inserire gli elementi nel controller

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

Ora se utilizzerai in questo modo:

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

in questo caso editId non sarà definito. Devi iniettarlo, in questo modo:

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

Ora funzionerà senza problemi, devo affrontare lo stesso problema molte volte, una volta iniettato, tutto inizia a funzionare!


Come ogni cosa Angular, l'iniezione è la soluzione. Grazie!
Sebastialonso

questo errore indefinito mi stava facendo la testa finché non ho visto la tua risposta! Funziona come un fascino!
Dan

Come fai se invece di una semplice var vuoi passare un oggetto timeout? la risoluzione non si attiverà fino a quando il timeout non sarà stato risolto, cosa che accade alla fine del timeout
Danny22

La cosa che mi mancava nella mia soluzione era usare $ scope e $ location tra virgolette semplici .... Non sapevo che quegli argomenti dovevano essere stringhe
rshimoda

1
In questo modo ottengo "angular.js: 10071 Errore: [$ injector: unpr] Provider sconosciuto: editIdProvider <- editId". Qualche idea?
Oskar Lund

57

L'altro non funziona. Secondo i documenti questo è il modo in cui dovresti farlo.

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

Vedi plunkr


1
Non dovresti racchiuderlo come ['$ scope', '$ modalInstance', function () per iniettare le dipendenze?
joseramonc

1
Grazie per il commento, Jose, quello era esattamente il mio problema. Se stai minimizzando il tuo codice angolare, sì, devi usare la sintassi dell'array per ModalInstanceCtrl.
mcole

Jose, +1 Era anche un mio problema. E penso a tutti quelli che usano AngularUI!
Matteo Defanti

50

In alternativa è possibile creare un nuovo ambito e passare attraverso i parametri tramite l'opzione scope

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

Nel tuo controller modale passa in $ scope, quindi non è necessario passare e itemsProvider o qualsiasi altra soluzione che hai chiamato

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

2
$ rootScope. $ new (); <=== questo dovrebbe essere votato. trucco molto accurato. Grazie!
reflog

3
+1 Poiché ciò consente il passaggio dei dati senza dover definire un controller per il modale. A proposito, puoi semplicemente $scope.$new(true)creare un nuovo ambito isolato senza la necessità di iniettare $rootScope.
Santosh

@Mwayi: grazie per questo suggerimento! Il problema con l'iniezione classica (usando resolve) è che gli argomenti sono obbligatori, quindi ogni volta che apri un modale, devi risolvere tutti gli argomenti o la chiamata a $modal.open()fallirà perché il controllore vuole i suoi argomenti. Usando questo semplice scopetrucco, le dipendenze diventano opzionali.
impilabile

23

Puoi anche passare facilmente i parametri al controller modale aggiungendo una nuova proprietà con l'istanza di modal e portarlo al controller modale. Per esempio:

Di seguito è riportato il mio evento clic su cui desidero aprire la visualizzazione 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';
        };

Controller modale:

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

Esattamente quello di cui avevo bisogno. Ha funzionato perfettamente.
theFish

17

Ho provato come di seguito.

Ho chiamato il ng-clickcontroller angularjs sul pulsante Incoraggia ,

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

Ho impostato userNamesu encouragementModalda angularjs controller.

    /**
     * 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' ];

Ho fornito un place ( userName) per ottenere valore dal controller 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>

Ha funzionato e mi sono salutato.


3
Faccio +1 e ti saluto. Se qualcuno ha bisogno di passare l'intero utente al modal piuttosto che una singola stringa per il suo nome, nel controller, ricordati di usare angular.copy(user).
tuo

10

Dovresti davvero usare l'interfaccia utente angolare per queste esigenze. Check it out: Angular UI Dialog

In poche parole, con la finestra di dialogo dell'interfaccia utente angolare, puoi passare una variabile da un controller al controller di dialogo utilizzando resolve. Ecco il tuo controller "da":

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

E nel controller di dialogo:

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

EDIT: dalla nuova versione dell'interfaccia utente, la voce di risoluzione diventa:

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


Ciao, non ho provato in questo modo. Ma +1 per un suggerimento.
Prayagupd

3
in realtà dovrebbe essereresolve: function(){return {username: 'foo'}}
SET

La risposta SET non funzionerà. la bicicletta ce l'ha proprio sotto, dovrebbe essere - risolvere: {data: function () {return 'foo';}}
bornytm

1
@bornytm Al giorno d'oggi hai ragione. Ma quando la mia risposta è stata scritta, la sintassi era:resolve: { username: 'foo'}
Sandro Munda

4

Puoi semplicemente creare una funzione controller e passare i tuoi parametri con l'oggetto $ scope.

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

1

Se non stai usando AngularJS UI Bootstrap, ecco come l'ho fatto.

Ho creato una direttiva che manterrà l'intero elemento del tuo modal e ricompilo l'elemento per iniettare il tuo ambito in esso.

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

Presumo che il tuo modello modale sia all'interno dell'ambito del tuo controller, quindi aggiungi la direttiva my-modal al tuo modello. Se hai salvato l'utente su cui è stato fatto clic in $ scope.aModel , il modello originale ora funzionerà.

Nota: l'intero ambito è ora visibile al tuo modal, quindi puoi anche accedere a $ scope.users al suo interno.

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.