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?

prayagupd
źródło
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ć!

Ali Adravi
źródło
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

rower
źródło
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)
}
Mwayi
źródło
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...
                }]);
Rubi saini
źródło
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.

prayagupd
źródło
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'; } }

Sandro Munda
źródło
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;
      }
    });
}
itay oded
źródło
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>
elitechance
źródło