Wie übergebe ich Parameter an ein Modal?


96

Ich möchte die userNameaus einer Liste der userNameangemeldeten Benutzerklicks an den Twitter-Bootstrap weiterleiten modal. Ich verwende Grails mit AngularJs , bei denen Daten über AngularJs gerendert werden .

Aufbau

Meine Grals-Ansichtsseite encouragement.gspist

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

Mein encourage/_encouragement_modal.gspist

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

Also, wie kann ich passieren userNamezu encouragementModal?


1
Sie sollten diese Dinge mit anglejs behandeln. Kasse ng-include.
zs2020

Antworten:


149

Um den Parameter zu übergeben, müssen Sie die Elemente auflösen und in den Controller einfügen

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

Nun, wenn Sie wie folgt verwenden:

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

In diesem Fall ist editId undefiniert. Sie müssen es wie folgt injizieren:

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

Jetzt wird es reibungslos funktionieren, ich habe viele Male das gleiche Problem, sobald es injiziert ist, fängt alles an zu funktionieren!


Wie alles Angular ist die Injektion die Lösung. Vielen Dank!
Sebastialonso

Dieser undefinierte Fehler hat mir den Kopf verdreht, bis ich Ihre Antwort sah! Klappt wunderbar!
Dan

Wie gehen Sie vor, wenn Sie anstelle einer einfachen Variable ein Timeout-Objekt übergeben möchten? Die Auflösung wird erst
ausgelöst, wenn

Das, was mir in meiner Lösung fehlte, war, $ scope und $ location zwischen einfachen Anführungszeichen zu verwenden ... Ich wusste nicht, dass diese Argumente Zeichenfolgen sein mussten
rshimoda

1
Dabei erhalte ich "angle.js: 10071 Fehler: [$ injor: unpr] Unbekannter Anbieter: editIdProvider <- editId". Irgendwelche Ideen?
Oskar Lund

57

Der andere funktioniert nicht. Laut den Dokumenten sollten Sie dies so tun.

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

Siehe plunkr


1
Sie sollten dies nicht wie ['$ scope', '$ modalInstance', function () umschließen, um Abhängigkeiten einzufügen?
Joseramonc

1
Danke für den Kommentar, Jose, das war genau mein Problem. Wenn Sie Ihren Angular-Code minimieren, müssen Sie die Array-Syntax für ModalInstanceCtrl verwenden.
Mcole

Jose, +1 Es war auch mein Problem. Und ich denke an alle, die AngularUI verwenden!
Matteo Defanti

50

Alternativ können Sie einen neuen Bereich erstellen und Parameter über die Option scope übergeben

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

Wenn Sie Ihren modalen Controller in $ scope übergeben, müssen Sie dann nicht und itemsProvider oder eine von Ihnen benannte Lösung übergeben

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

2
$ rootScope. $ new (); <=== dies sollte positiv bewertet werden. sehr ordentlicher Trick. Vielen Dank!
Reflog

3
+1 Da dies das Übergeben von Daten ermöglicht, ohne dass ein Controller für das Modal definiert werden muss. Übrigens können Sie einfach $scope.$new(true)einen neuen isolierten Bereich erstellen, ohne ihn injizieren zu müssen $rootScope.
Santosh

@Mwayi: Danke für diesen Tipp! Das Problem bei der klassischen Injektion (using resolve) besteht darin, dass die Argumente obligatorisch sind. Jedes Mal, wenn Sie ein Modal öffnen, müssen Sie alle Argumente auflösen. Andernfalls schlägt der Aufruf von $modal.open()fehl, da der Controller seine Argumente wünscht . Mit diesem netten scopeTrick werden Abhängigkeiten optional.
Stapel

23

Sie können Parameter auch einfach an den Modal Controller übergeben, indem Sie eine neue Eigenschaft mit der Instanz von Modal hinzufügen und an den Modal Controller übertragen. Beispielsweise:

Es folgt mein Klickereignis, bei dem ich die modale Ansicht öffnen möchte.

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

Modal Controller:

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

Genau das, was ich brauchte. Hat perfekt funktioniert.
TheFish

17

Ich habe es wie unten versucht.

Ich habe ng-clickden AngularJS-Controller über die Schaltfläche " Ermutigen" angerufen .

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

Ich habe userNamevon encouragementModalvon 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' ];

Ich habe einen Platz ( userName) angegeben, um den Wert vom AngleJS-Controller einzuschalten 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>

Es hat funktioniert und ich habe mich begrüßt.


3
Ich +1 und ich grüße dich. Wenn jemand den gesamten Benutzer an das Modal und nicht an eine einzelne Zeichenfolge für seinen Namen übergeben muss, denken Sie daran, diese im Controller zu verwenden angular.copy(user).
Youri

10

Sie sollten Angular UI wirklich für diese Anforderungen verwenden. Probieren Sie es aus: Angular UI Dialog

Kurz gesagt, mit dem Dialogfeld "Angular UI" können Sie mithilfe von Variablen eine Variable von einem Controller an den Dialog-Controller übergeben resolve. Hier ist Ihr "Von" -Controller:

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

Und in Ihrem Dialog-Controller:

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

BEARBEITEN: Seit der neuen Version des UI-Dialogs lautet der Auflösungseintrag:

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


Hallo, ich habe es nicht so versucht. Aber +1 für einen Vorschlag.
Prayagupd

3
Eigentlich sollte das seinresolve: function(){return {username: 'foo'}}
SET

Die Antwort von SETs funktioniert nicht. Fahrrad hat es direkt unten, es sollte aufgelöst werden: {data: function () {return 'foo';}}
bornytm

1
@bornytm Heutzutage hast du recht. Aber als meine Antwort geschrieben wurde, war die Syntax:resolve: { username: 'foo'}
Sandro Munda

4

Sie können einfach eine Controller-Funktion erstellen und Ihre Parameter mit dem $ scope-Objekt übergeben.

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

1

Wenn Sie AngularJS UI Bootstrap nicht verwenden, habe ich Folgendes getan.

Ich habe eine Direktive erstellt, die das gesamte Element Ihres Modals enthält, und das Element neu kompiliert, um Ihren Gültigkeitsbereich darin einzufügen.

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

Ich gehe davon aus, dass sich Ihre modale Vorlage im Bereich Ihres Controllers befindet, und füge dann Ihrer Vorlage die Direktive my-modal hinzu . Wenn Sie den angeklickten Benutzer in $ scope.aModel gespeichert haben , funktioniert die ursprüngliche Vorlage jetzt.

Hinweis: Der gesamte Bereich ist jetzt für Ihr Modal sichtbar, sodass Sie auch auf $ scope.users zugreifen können.

<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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.