如何向模态传递参数?

我想从一个登录用户点击到 Bootstrap modaluserName列表中传递 userName。 我使用 圣杯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呢?

203986 次浏览

You should really use Angular UI for that needs. Check it out: Angular UI Dialog

In a nutshell, with Angular UI dialog, you can pass variable from a controller to the dialog controller using resolve. Here's your "from" 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();

And in your dialog controller:

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

EDIT: Since the new version of the ui-dialog, the resolve entry becomes:

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

I tried as below.

I called ng-click to angularjs controller on Encourage button,

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

I set userName of encouragementModal from 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' ];

I provided a place(userName) to get value from angularjs controller on 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>

It worked and I saluted myself.

The other one doesn't work. According to the docs this is the way you should do it.

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

See plunkr

To pass the parameter you need to use resolve and inject the items in controller

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

Now if you will use like this:

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

in this case editId will be undefined. You need to inject it, like this:

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

Now it will work smooth, I face the same problem many time, once injected, everything start working!

Alternatively you can create a new scope and pass through params via the scope option

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

In your modal controller pass in $scope, you then do not need to pass in and itemsProvider or what ever resolve you named it

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

If you're not using AngularJS UI Bootstrap, here's how I did it.

I created a directive that will hold that entire element of your modal, and recompile the element to inject your scope into it.

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

I'm assuming your modal template is inside the scope of your controller, then add directive my-modal to your template. If you saved the clicked user to $scope.aModel, the original template will now work.

Note: The entire scope is now visible to your modal so you can also access $scope.users in it.

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

You can also easily pass parameters to modal controller by added a new property with instance of modal and get it to modal controller. For example:

Following is my click event on which i want to open modal view.

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

You can simply create a controller funciton and pass your parameters with the $scope object.

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