Reputation: 15249
I have mainly to open an angular popup window based on a template. But I need to obtain the data from an ajax call.
The Module sample explains how to use a template, but I am confused where to place an ajax call to obtain the items, like follows (the snippet is not working, but is the same as the sample):
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl',
function($scope, $uibModal, $log) {
//
// need to obtain these items from an AJAX/GET call
//
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function(size) {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">...</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">...</li>
</ul>
</div>
<div class="modal-footer">...</div>
</script>
<button type="button" ng-click="open()">Open me!</button>
</div>
I have a link that return JSON data, I'd modify the function like this:
$scope.open = function(size, jsonLink) {
var modalInstance = $uibModal.open({
// ?????
templateJsonUrl: jsonLink,
// ?????
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});
Upvotes: 3
Views: 1260
Reputation: 12892
Just make a request with a http
service, and assign result to $scope.items
when it will be resolved. A digest cycle will make bindings. Don't forget to inject http
service itself.
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl',
function($scope, $http, $uibModal, $log) {
$http
.post('/your_pass_to_json.json', data)
.then(function(data) {
$scope.items = data.items;
});
$scope.open = function(size) {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});
Here is plunker, but I've assigned $scope.items
in the promise rejection because could not mock the XHR request.
UPDATE
Or you can put modal opening in the xhr callback:
$scope.open = function(size) {
$http
.post('/your_pass_to_json.json', data)
.then(function(data) {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return data.tiems;
}
}
});
});
}
In this case, the modal will always be opened with a delay. I would suggest you to make an xhr
request once the controller was initialized, and make a verification on the opening event: if xhr was already fired before, take items from $scope
, if it wasn't, cancel previous request and make a new one.
Upvotes: 3
Reputation: 423
@Lazarev's answer is correct, but additionally in Angular, you have to make ajax calls from angular services and directly inject to controllers.
like this; AngularJS Ajax Call in Service
Upvotes: 1