Angularjs ui-modal 不能正常处理 $http 请求
Angularjs ui-modal is not working properly with $http request
我正在使用 Angularjs 1.5.x 和 AngularUI Bootstrap
我正在尝试打开一个 bootstrap 模式并使用 $http 请求用远程数据填充它。
我正在使用 modal 的打开实例的 resolve 方法来触发 $http 请求并获取数据。之后我更新了一个局部变量并 return 它。但是,$http 正在正确获取数据,但本地范围变量未正确更新,并且它在模板中一直显示为空数组。
代码:
app.controller('ModalCtrl', function ($uibModal, $log, $document, $rootScope, $http) {
var $cctrl = this;
$cctrl.modalData = [];
$cctrl.animationsEnabled = true;
$cctrl.open = function (size, templateUrl, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
var modalInstance = $uibModal.open({
animation: $cctrl.animationsEnabled,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: templateUrl,
controller: 'ModalInstanceCtrl',
controllerAs: '$cctrl',
size: size,
appendTo: parentElem,
resolve: {
modalData: function () {
var url;
var reqData;
var config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'responseType': 'json',
'cache': false
}
};
if (templateUrl == 'test.html') {
reqData = $.param({
lclasses: ($rootScope.activeTruck.truck.LicenceClassesRequired || ''),
subbie: ($rootScope.activeTruck.truck.subbie || '0')
});
url = 'index.php?module=test&task=fetchJSON';
}
$http.post(url, reqData, config).then(function (response) {
console.log("Success");
console.log(response); //here, response fetched data success
$cctrl.modalData = response.data;
console.log($cctrl.modalData); //here, its [] data
return $cctrl.modalData;
}, function (response) {
console.log("Failed");
console.log(response);
});
}
}
});
modalInstance.result.then(function (selectedItem) {
console.log("opened");
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
app.controller('ModalInstanceCtrl', function ($uibModalInstance, modalData) {
var $cctrl = this;
console.log(modalData);
$cctrl.modalData = modalData;
$cctrl.ok = function () {
//$uibModalInstance.close($cctrl.selected.item);
$uibModalInstance.close();
};
$cctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
这里工作正常...
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
var $cctrl = this;
$cctrl.items = [
{
"id": 0,
"picture": "https://ultimatemotorcycling.com/wp-content/uploads/2011/11/2012-ducati-panigale-1199-preview-5.jpg",
"age": 31,
"name": "Mathews Goff",
"company": "FXA"
},
{
"id": 1,
"picture": "http://placehold.it/32x32",
"age": 36,
"name": "Collins Alston"
},
{
"id": 2,
"picture": "http://placehold.it/32x32",
"age": 27,
"name": "Jasmine Rollins"
},
{
"id": 3,
"picture": "http://placehold.it/32x32",
"age": 32,
"name": "Julie Jefferson"
},
{
"id": 4,
"picture": "http://placehold.it/32x32",
"age": 23,
"name": "Wilder King"
},
{
"id": 5,
"picture": "http://placehold.it/32x32",
"age": 23,
"name": "Stanley Moore"
},
{
"id": 6,
"picture": "http://placehold.it/32x32",
"age": 36,
"name": "Reynolds Bishop"
},
{
"id": 7,
"picture": "http://placehold.it/32x32",
"age": 26,
"name": "Bryant Flowers"
},
{
"id": 8,
"picture": "http://placehold.it/32x32",
"age": 38,
"name": "Jenifer Martinez"
},
{
"id": 9,
"picture": "http://placehold.it/32x32",
"age": 40,
"name": "Mcguire Pittman"
},
{
"id": 10,
"picture": "http://placehold.it/32x32",
"age": 34,
"name": "Valdez Hyde"
},
{
"id": 11,
"picture": "http://placehold.it/32x32",
"age": 34,
"name": "Marla Mayo"
},
{
"id": 12,
"picture": "http://placehold.it/32x32",
"age": 30,
"name": "Brown Ortega"
},
{
"id": 13,
"picture": "http://placehold.it/32x32",
"age": 32,
"name": "Jeannette William"
},
{
"id": 14,
"picture": "http://placehold.it/32x32",
"age": 30,
"name": "Bridges Ashley"
},
{
"id": 15,
"picture": "http://placehold.it/32x32",
"age": 33,
"name": "Latasha Hewitt"
},
{
"id": 16,
"picture": "http://placehold.it/32x32",
"age": 35,
"name": "Alma Sawyer"
},
{
"id": 17,
"picture": "http://placehold.it/32x32",
"age": 21,
"name": "Liz Mcbride"
},
{
"id": 18,
"picture": "http://placehold.it/32x32",
"age": 26,
"name": "Mcintosh Chandler"
},
{
"id": 19,
"picture": "http://placehold.it/32x32",
"age": 20,
"name": "Alford Hartman"
},
{
"id": 20,
"picture": "http://placehold.it/32x32",
"age": 29,
"name": "Tiffany Green"
},
{
"id": 21,
"picture": "http://placehold.it/32x32",
"age": 38,
"name": "Stafford Riggs"
},
{
"id": 22,
"picture": "http://placehold.it/32x32",
"age": 40,
"name": "Elinor Chambers"
},
{
"id": 23,
"picture": "http://placehold.it/32x32",
"age": 27,
"name": "Carly Howard"
},
{
"id": 24,
"picture": "http://placehold.it/32x32",
"age": 27,
"name": "Rosalind Sanchez"
},
{
"id": 25,
"picture": "http://placehold.it/32x32",
"age": 28,
"name": "Jaclyn Shelton"
},
{
"id": 26,
"picture": "http://placehold.it/32x32",
"age": 25,
"name": "Hughes Phelps"
},
{
"id": 27,
"picture": "http://placehold.it/32x32",
"age": 36,
"name": "Rosetta Barrett"
},
{
"id": 28,
"picture": "http://placehold.it/32x32",
"age": 29,
"name": "Jarvis Wong"
},
{
"id": 29,
"picture": "http://placehold.it/32x32",
"age": 23,
"name": "Kerri Pennington"
}
];
$cctrl.open = function (size) {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
controllerAs:'$cctrl',
resolve: {
items: function () {
return $cctrl.items;
},
size: function() {
// console.log('size: ', size);
return size;
}
}
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items, size) {
var $cctrl = this;
$cctrl.items = items;
$cctrl.selected = {
item: $cctrl.items[0]
};
$cctrl.size = size;
// console.log('size in ctrl: ', size);
$cctrl.ok = function () {
$uibModalInstance.close($cctrl.selected.item);
};
$cctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<style>
.grid {
border: solid 1px #ccc padding: 10px 10px 0 0;
}
.grid li {
display: inline-block;
width: 100px;
height: 200px;
border: solid 1px #ccc;
margin: 0 0 10px 10px;
background: #eee;
}
/**** Transitions ****/
.masonry,
.masonry li { /* apply before masonry add class */
position: absolute; /* important to add it before enter animation start */
-webkit-transition-duration: .7s;
transition-duration: .7s;
-webkit-transition-property: all;
transition-property: all;
}
.masonry .masonry-enter { /* limit animated properties for entering elements */
-webkit-transition-property: -webkit-transform, opacity;
transition-property: transform, opacity;
}
.masonry-enter,
.masonry-leave.masonry-leave-active {
opacity: 0;
-webkit-transform: scale(0.1);
transform: scale(0.1);
}
.masonry-leave,
.masonry-enter.masonry-enter-active {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/masonry/2.1.08/jquery.masonry.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<!--<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl as ctrl">
<input type="text" ng-model="nameFilter" />
<a href="#" ng-click="order = 'id'">Order by id</a>
<a href="#" ng-click="order = 'name'">Order by name</a>
<a href="#" ng-click="order = 'age'">Order by age</a>
<ul class="grid" masonry="true">
<li ng-repeat="item in ctrl.items | filter: { name: nameFilter } | orderBy: order">
<span>{{item.name}}</span>
<br /> <span>Age: {{item.age}}</span>
<br /> <span>Company: {{item.company}}</span>
<img ng-src="{{item.picture}}" width="100" ng-click="ctrl.open(item)"/>
</li>
</ul>
</div>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
{{$cctrl.size.name}} {{$cctrl.selected}}
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="$cctrl.ok()">OK</button>
<button class="btn btn-warning" ng-click="$cctrl.cancel()">Cancel</button>
</div>
</script>
</body>
</html>
像下面这样尝试..
$http.post(url, reqData, config).then(function (response) {
return response.data; //return your response data directly
}
在 ModalInstanceCtrl
控制器中,您可以得到如下所示。
$cctrl.modalData = modalData;
我正在使用 Angularjs 1.5.x 和 AngularUI Bootstrap
我正在尝试打开一个 bootstrap 模式并使用 $http 请求用远程数据填充它。
我正在使用 modal 的打开实例的 resolve 方法来触发 $http 请求并获取数据。之后我更新了一个局部变量并 return 它。但是,$http 正在正确获取数据,但本地范围变量未正确更新,并且它在模板中一直显示为空数组。
代码:
app.controller('ModalCtrl', function ($uibModal, $log, $document, $rootScope, $http) {
var $cctrl = this;
$cctrl.modalData = [];
$cctrl.animationsEnabled = true;
$cctrl.open = function (size, templateUrl, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
var modalInstance = $uibModal.open({
animation: $cctrl.animationsEnabled,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: templateUrl,
controller: 'ModalInstanceCtrl',
controllerAs: '$cctrl',
size: size,
appendTo: parentElem,
resolve: {
modalData: function () {
var url;
var reqData;
var config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'responseType': 'json',
'cache': false
}
};
if (templateUrl == 'test.html') {
reqData = $.param({
lclasses: ($rootScope.activeTruck.truck.LicenceClassesRequired || ''),
subbie: ($rootScope.activeTruck.truck.subbie || '0')
});
url = 'index.php?module=test&task=fetchJSON';
}
$http.post(url, reqData, config).then(function (response) {
console.log("Success");
console.log(response); //here, response fetched data success
$cctrl.modalData = response.data;
console.log($cctrl.modalData); //here, its [] data
return $cctrl.modalData;
}, function (response) {
console.log("Failed");
console.log(response);
});
}
}
});
modalInstance.result.then(function (selectedItem) {
console.log("opened");
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
app.controller('ModalInstanceCtrl', function ($uibModalInstance, modalData) {
var $cctrl = this;
console.log(modalData);
$cctrl.modalData = modalData;
$cctrl.ok = function () {
//$uibModalInstance.close($cctrl.selected.item);
$uibModalInstance.close();
};
$cctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
这里工作正常...
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
var $cctrl = this;
$cctrl.items = [
{
"id": 0,
"picture": "https://ultimatemotorcycling.com/wp-content/uploads/2011/11/2012-ducati-panigale-1199-preview-5.jpg",
"age": 31,
"name": "Mathews Goff",
"company": "FXA"
},
{
"id": 1,
"picture": "http://placehold.it/32x32",
"age": 36,
"name": "Collins Alston"
},
{
"id": 2,
"picture": "http://placehold.it/32x32",
"age": 27,
"name": "Jasmine Rollins"
},
{
"id": 3,
"picture": "http://placehold.it/32x32",
"age": 32,
"name": "Julie Jefferson"
},
{
"id": 4,
"picture": "http://placehold.it/32x32",
"age": 23,
"name": "Wilder King"
},
{
"id": 5,
"picture": "http://placehold.it/32x32",
"age": 23,
"name": "Stanley Moore"
},
{
"id": 6,
"picture": "http://placehold.it/32x32",
"age": 36,
"name": "Reynolds Bishop"
},
{
"id": 7,
"picture": "http://placehold.it/32x32",
"age": 26,
"name": "Bryant Flowers"
},
{
"id": 8,
"picture": "http://placehold.it/32x32",
"age": 38,
"name": "Jenifer Martinez"
},
{
"id": 9,
"picture": "http://placehold.it/32x32",
"age": 40,
"name": "Mcguire Pittman"
},
{
"id": 10,
"picture": "http://placehold.it/32x32",
"age": 34,
"name": "Valdez Hyde"
},
{
"id": 11,
"picture": "http://placehold.it/32x32",
"age": 34,
"name": "Marla Mayo"
},
{
"id": 12,
"picture": "http://placehold.it/32x32",
"age": 30,
"name": "Brown Ortega"
},
{
"id": 13,
"picture": "http://placehold.it/32x32",
"age": 32,
"name": "Jeannette William"
},
{
"id": 14,
"picture": "http://placehold.it/32x32",
"age": 30,
"name": "Bridges Ashley"
},
{
"id": 15,
"picture": "http://placehold.it/32x32",
"age": 33,
"name": "Latasha Hewitt"
},
{
"id": 16,
"picture": "http://placehold.it/32x32",
"age": 35,
"name": "Alma Sawyer"
},
{
"id": 17,
"picture": "http://placehold.it/32x32",
"age": 21,
"name": "Liz Mcbride"
},
{
"id": 18,
"picture": "http://placehold.it/32x32",
"age": 26,
"name": "Mcintosh Chandler"
},
{
"id": 19,
"picture": "http://placehold.it/32x32",
"age": 20,
"name": "Alford Hartman"
},
{
"id": 20,
"picture": "http://placehold.it/32x32",
"age": 29,
"name": "Tiffany Green"
},
{
"id": 21,
"picture": "http://placehold.it/32x32",
"age": 38,
"name": "Stafford Riggs"
},
{
"id": 22,
"picture": "http://placehold.it/32x32",
"age": 40,
"name": "Elinor Chambers"
},
{
"id": 23,
"picture": "http://placehold.it/32x32",
"age": 27,
"name": "Carly Howard"
},
{
"id": 24,
"picture": "http://placehold.it/32x32",
"age": 27,
"name": "Rosalind Sanchez"
},
{
"id": 25,
"picture": "http://placehold.it/32x32",
"age": 28,
"name": "Jaclyn Shelton"
},
{
"id": 26,
"picture": "http://placehold.it/32x32",
"age": 25,
"name": "Hughes Phelps"
},
{
"id": 27,
"picture": "http://placehold.it/32x32",
"age": 36,
"name": "Rosetta Barrett"
},
{
"id": 28,
"picture": "http://placehold.it/32x32",
"age": 29,
"name": "Jarvis Wong"
},
{
"id": 29,
"picture": "http://placehold.it/32x32",
"age": 23,
"name": "Kerri Pennington"
}
];
$cctrl.open = function (size) {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
controllerAs:'$cctrl',
resolve: {
items: function () {
return $cctrl.items;
},
size: function() {
// console.log('size: ', size);
return size;
}
}
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items, size) {
var $cctrl = this;
$cctrl.items = items;
$cctrl.selected = {
item: $cctrl.items[0]
};
$cctrl.size = size;
// console.log('size in ctrl: ', size);
$cctrl.ok = function () {
$uibModalInstance.close($cctrl.selected.item);
};
$cctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<style>
.grid {
border: solid 1px #ccc padding: 10px 10px 0 0;
}
.grid li {
display: inline-block;
width: 100px;
height: 200px;
border: solid 1px #ccc;
margin: 0 0 10px 10px;
background: #eee;
}
/**** Transitions ****/
.masonry,
.masonry li { /* apply before masonry add class */
position: absolute; /* important to add it before enter animation start */
-webkit-transition-duration: .7s;
transition-duration: .7s;
-webkit-transition-property: all;
transition-property: all;
}
.masonry .masonry-enter { /* limit animated properties for entering elements */
-webkit-transition-property: -webkit-transform, opacity;
transition-property: transform, opacity;
}
.masonry-enter,
.masonry-leave.masonry-leave-active {
opacity: 0;
-webkit-transform: scale(0.1);
transform: scale(0.1);
}
.masonry-leave,
.masonry-enter.masonry-enter-active {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/masonry/2.1.08/jquery.masonry.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<!--<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl as ctrl">
<input type="text" ng-model="nameFilter" />
<a href="#" ng-click="order = 'id'">Order by id</a>
<a href="#" ng-click="order = 'name'">Order by name</a>
<a href="#" ng-click="order = 'age'">Order by age</a>
<ul class="grid" masonry="true">
<li ng-repeat="item in ctrl.items | filter: { name: nameFilter } | orderBy: order">
<span>{{item.name}}</span>
<br /> <span>Age: {{item.age}}</span>
<br /> <span>Company: {{item.company}}</span>
<img ng-src="{{item.picture}}" width="100" ng-click="ctrl.open(item)"/>
</li>
</ul>
</div>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
{{$cctrl.size.name}} {{$cctrl.selected}}
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="$cctrl.ok()">OK</button>
<button class="btn btn-warning" ng-click="$cctrl.cancel()">Cancel</button>
</div>
</script>
</body>
</html>
像下面这样尝试..
$http.post(url, reqData, config).then(function (response) {
return response.data; //return your response data directly
}
在 ModalInstanceCtrl
控制器中,您可以得到如下所示。
$cctrl.modalData = modalData;