Как передать параметры в модальное окно?

96

Я хочу передать userNameиз списка userNamesa, вошедшего в систему, пользователь нажимает на twitter bootstrap modal. Я использую grails с angularjs , где данные отображаются через angularjs .

Конфигурация

Мой Grails просмотр страницы 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>

Мое 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>

Итак, как я могу перейти userNameна encouragementModal?

прайагупд
источник
1
Вы должны справиться с этим с помощью angularjs. оформить заказ ng-include.
zs2020 02

Ответы:

149

Чтобы передать параметр, вам нужно использовать разрешение и ввести элементы в контроллер

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

Теперь, если вы будете использовать вот так:

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

в этом случае editId будет неопределенным. Его нужно вводить, например:

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

Теперь он будет работать гладко, я сталкиваюсь с одной и той же проблемой много раз, после инъекции все начинает работать!

Али Адрави
источник
Как и любой другой Angular, решение - инъекция. Спасибо!
Sebastialonso
эта неопределенная ошибка мучила меня, пока я не увидел ваш ответ! Работает как шарм!
Дэн
Что делать, если вместо простого var вы хотите передать какой-то объект тайм-аута? решение не сработает до тех пор, пока не будет разрешен тайм-аут, что происходит в конце тайм-аута
Дэнни, 22
В моем решении мне не хватало $ scope и $ location между простыми кавычками .... Я не знал, что эти аргументы должны быть строками
rshimoda
1
При этом я получаю "angular.js: 10071 Ошибка: [$ injector: unpr] Неизвестный провайдер: editIdProvider <- editId". Любые идеи?
Оскар Лунд
57

Другой не работает. Согласно документам, вы должны это сделать.

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

См. Plunkr

велосипед
источник
1
Вы не должны оборачивать это как ['$ scope', '$ modalInstance', function (), чтобы внедрить зависимости?
joseramonc
1
Спасибо за комментарий, Хосе, это была моя проблема. Если вы минимизируете свой код Angular, да, вам нужно использовать синтаксис массива для ModalInstanceCtrl.
mcole
Хосе, +1 Это тоже была моя проблема. И я думаю обо всех, кто использует AngularUI!
Маттео Дефанти,
50

В качестве альтернативы вы можете создать новую область и передать параметры через параметр области

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

В вашем модальном контроллере перейдите в $ scope, тогда вам не нужно передавать и itemsProvider или что-то еще, что вы назвали

modalController = function($scope) {
    console.log($scope.params)
}
Mwayi
источник
2
$ rootScope. $ new (); <=== за это нужно проголосовать. очень аккуратный трюк. Спасибо!
reflog 02
3
+1 Так как это позволяет передавать данные без необходимости определять контроллер для модального окна. Кстати, вы можете просто $scope.$new(true)создать новую изолированную область без необходимости вводить $rootScope.
Santosh
@Mwayi: Спасибо за этот совет! Проблема с классическим внедрением (использованием resolve) заключается в том, что аргументы являются обязательными, поэтому каждый раз, когда вы открываете модальное окно, вы должны разрешать все аргументы, иначе вызов $modal.open()завершится неудачно, потому что контроллеру нужны его аргументы. Используя этот изящный scopeтрюк, зависимости становятся необязательными.
stackular
23

Вы также можете легко передать параметры модальному контроллеру, добавив новое свойство с экземпляром модального окна и передать его модальному контроллеру. Например:

Ниже приведено мое событие щелчка, для которого я хочу открыть модальное представление.

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

Модальный контроллер:

angular.module('myApp').controller('UserDetailCtrl', ['$modalInstance',
                function ($modalInstance) {
                    // get your parameter from modal instance
                    var currentUser = $modalInstance.userName;
                    // do your work...
                }]);
Руби сайни
источник
Именно то, что мне нужно. Работает отлично.
theFish
17

Я пробовал, как показано ниже.

Я позвонил ng-clickконтроллеру angularjs на кнопку поощрения ,

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

Я поставил userNameиз encouragementModalот 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' ];

Я предоставил место ( userName) для получения значения от контроллера 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>

Это сработало, и я отсалютовал себе.

прайагупд
источник
3
Я +1 и приветствую вас. Если кому-то нужно передать в модальное окно всего пользователя, а не одну строку для его имени, в контроллере не забудьте использовать angular.copy(user).
youri
10

Для этого вам действительно стоит использовать Angular UI. Проверьте это: Angular UI Dialog

Вкратце, с помощью диалогового окна Angular UI вы можете передавать переменную из контроллера в контроллер диалога, используя resolve. Вот ваш контроллер "от":

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

И в вашем контроллере диалога:

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

РЕДАКТИРОВАТЬ: Начиная с новой версии ui-dialog, запись разрешения становится:

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

Сандро Мунда
источник
Привет, я так не пробовал. Но +1 за предложение.
прайагупд 03
3
на самом деле так и должно бытьresolve: function(){return {username: 'foo'}}
ВЫСТАВЛЕНО
Ответ SET не сработает. Велосипед имеет это право ниже, оно должно быть- постановляю: {данные: функция () {возвращение 'Foo';}}
bornytm
1
@bornytm Сейчас ты прав. Но когда был написан мой ответ, синтаксис был:resolve: { username: 'foo'}
Сандро Мунда,
4

Вы можете просто создать функцию контроллера и передать свои параметры с помощью объекта $ scope.

$scope.Edit = function (modalParam) {
var modalInstance = $modal.open({
      templateUrl: '/app/views/admin/addeditphone.html',
      controller: function($scope) {
        $scope.modalParam = modalParam;
      }
    });
}
Itay Oded
источник
1

Если вы не используете AngularJS UI Bootstrap, вот как я это сделал.

Я создал директиву, которая будет содержать весь этот элемент вашего модального окна, и перекомпилировать элемент, чтобы добавить в него вашу область видимости.

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

Я предполагаю, что ваш модальный шаблон находится в области действия вашего контроллера, а затем добавьте директиву my-modal в свой шаблон. Если вы сохранили пользователя, которого щелкнули, в $ scope.aModel , исходный шаблон теперь будет работать.

Примечание: вся область видимости теперь видна вашему модальному окну, поэтому вы также можете получить доступ окну, в нем $ 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>
элитный шанс
источник