Jak przekazać parametry do modalu?


96

Chcę przekazać userNamez listy użytkowników, którzy są userNamezalogowani, do programu ładującego Twittera modal. Używam Grails z angularjs , gdzie dane są świadczone poprzez angularjs .

Konfiguracja

Moja strona widoku Grails encouragement.gspto

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

Mój encourage/_encouragement_modal.gspjest

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

Więc jak mogę przejść userNamedo encouragementModal?


1
Powinieneś poradzić sobie z tymi rzeczami za pomocą angularjs. Zamówienie ng-include.
— zs2020

Odpowiedzi:


149

Aby przekazać parametr, musisz użyć metody resell i wstrzyknąć elementy do kontrolera

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

Teraz, jeśli będziesz używać w ten sposób:

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

w tym przypadku editId będzie niezdefiniowane. Musisz to wstrzyknąć w ten sposób:

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

Teraz będzie działać gładko, wielokrotnie borykam się z tym samym problemem, po wstrzyknięciu wszystko zaczyna działać!


Jak wszystko Angular, rozwiązaniem jest zastrzyk. Dzięki!
— Sebastialonso,

ten nieokreślony błąd robił wrażenie, dopóki nie zobaczyłem twojej odpowiedzi! Działa jak marzenie!
— Dan

Jak to zrobić, jeśli zamiast zwykłego var chcesz przekazać jakiś obiekt timeout? postanowienie nie zostanie uruchomione, dopóki limit czasu nie zostanie rozwiązany, co dzieje się pod koniec limitu czasu
— Danny22

To, czego mi brakowało w moim rozwiązaniu, to użycie $ scope i $ location między prostymi cudzysłowami .... Nie wiedziałem, że te argumenty muszą być ciągami znaków
— rshimoda

1
W ten sposób otrzymuję „angular.js: 10071 Błąd: [$ injector: unpr] Nieznany dostawca: editIdProvider <- editId”. Jakieś pomysły?
— Oskar Lund

57

Drugi nie działa. Według dokumentacji jest to sposób, w jaki powinieneś to zrobić.

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

Zobacz plunkr


1
Nie powinieneś opakowywać tego w taki sposób, jak ['$ scope', '$ modalInstance', function (), aby wstrzyknąć zależności?
— joseramonc

1
Dzięki za komentarz, Jose, to był dokładnie mój problem. Jeśli minimalizujesz swój kod Angular, tak, musisz użyć składni tablicy dla ModalInstanceCtrl.
— mcole

Jose, +1 To też był mój problem. Myślę, że wszyscy używają AngularUI!
— Matteo Defanti

50

Alternatywnie możesz utworzyć nowy zasięg i przekazać parametry za pomocą opcji zakresu

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

W swoim przejściu kontrolera modalnego w $ scope, nie musisz wtedy przekazywać i itemsProvider ani czegokolwiek innego, co go nazwałeś

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

2
$ rootScope. $ new (); <=== to powinno być przegłosowane. bardzo zgrabna sztuczka. dzięki!
— reflog

3
+1 Ponieważ pozwala to na przekazywanie danych bez konieczności definiowania kontrolera dla modalu. BTW, możesz po prostu $scope.$new(true)stworzyć nowy izolowany zakres bez potrzeby wstrzykiwania $rootScope.
— Santosh

@Mwayi: Dzięki za tę wskazówkę! Problem z klasycznym wtryskiem (używanie resolve) polega na tym, że argumenty są obowiązkowe, więc za każdym razem, gdy otwierasz modal, musisz rozwiązać wszystkie argumenty, w przeciwnym razie wywołanie $modal.open()zakończy się niepowodzeniem, ponieważ kontroler chce swoich argumentów. Używając tej zgrabnej scopesztuczki, zależności stają się opcjonalne.
— stackular

23

Możesz również łatwo przekazać parametry do kontrolera modalnego, dodając nową właściwość z instancją modalną i pobrać ją do kontrolera modalnego. Na przykład:

Poniżej znajduje się moje zdarzenie kliknięcia, w którym chcę otworzyć widok modalny.

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

Kontroler modalny:

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

Dokładnie to, czego potrzebowałem. Działał doskonale.
— theFish

17

Próbowałem jak poniżej.

Zadzwoniłem ng-clickdo kontrolera angularjs na przycisk Zachęcaj ,

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

Ustawić userNameod encouragementModalod angularjs kontrolera.

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

userNamePodałem miejsce ( ), aby uzyskać wartość z kontrolera angularjs na 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>

Udało się i zasalutowałem sobie.


3
Daję +1 i pozdrawiam Cię. Jeśli ktoś potrzebuje przekazać całego użytkownika do modalu zamiast pojedynczego ciągu dla jej nazwy, w kontrolerze pamiętaj o użyciu angular.copy(user).
— youri

10

Naprawdę powinieneś używać Angular UI do tych potrzeb. Sprawdź to: Angular UI Dialog

Krótko mówiąc, za pomocą okna dialogowego Angular UI można przekazać zmienną z kontrolera do kontrolera dialogowego za pomocą resolve. Oto Twój kontroler „od”:

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

A w kontrolerze dialogu:

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

EDYCJA: Od nowej wersji okna dialogowego interfejsu użytkownika, pozycja rozwiązania zmienia się na:

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


Cześć, nie próbowałem w ten sposób. Ale +1 za sugestię.
— prayagupd

3
właściwie tak powinno byćresolve: function(){return {username: 'foo'}}
— SET

Odpowiedź SET nie zadziała. rower ma to tuż poniżej, powinno być- rozwiązać: {data: function () {return 'foo';}}
— bornytm

1
@bornytm Obecnie masz rację. Ale kiedy moja odpowiedź została napisana, składnia była następująca:resolve: { username: 'foo'}
— Sandro Munda,

4

Możesz po prostu utworzyć funkcję kontrolera i przekazać swoje parametry za pomocą obiektu $ scope.

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

1

Jeśli nie używasz AngularJS UI Bootstrap, oto jak to zrobiłem.

Stworzyłem dyrektywę, która będzie utrzymywać cały element twojego modalu i przekompiluj element, aby wstrzyknąć do niego twój zakres.

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

Zakładam, że twój szablon modalny znajduje się w zakresie twojego kontrolera, a następnie dodaj dyrektywę my-modal do twojego szablonu. Jeśli zapisałeś klikniętego użytkownika w $ scope.aModel , oryginalny szablon będzie teraz działał.

Uwaga: cały zakres jest teraz widoczny dla twojego modalu, więc możesz również uzyskać dostęp do $ scope.users w nim.

<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>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.