我在angular.js和$ http.get方法中使用工厂来获取和处理JSON数据。 JSON数据似乎已成功解析为工厂,但我有此JSON数据的访问属性问题。
这是我的js代码:
var app = angular.module("app", []);
app.factory('mainInfo', function($http) {
var obj = {content:null};
//the php will return json data below
$http.get('http://localhost/test.php').success(function(response){
obj.content = response.records;
});
return obj;
});
app.controller('Ctrl', function($scope, mainInfo){
$scope.foo = mainInfo.content;
}) ;
现在,如果我尝试在Ctrl
控制器中访问foo,则网页将不显示任何数据:
<div ng-controller="Ctrl">Controller: {{foo}}</div>
但是,如果我更改为$scope.foo = mainInfo
中的Ctrl
,则网页将正确显示JSON数据。
我是否知道在mainInfo.content
控制器中访问Ctrl
属性的正确方法是什么?
我需要访问JSON属性的原因是因为我需要预处理数据。我打算在图表中使用这些数据,如下面的控制器。目前这个控制器也没有工作,因为我在访问JSON属性时遇到了与Ctrl
控制器相同的问题。
app.controller("LineCtrl", function ($scope, mainInfo) {
var timePoints = [];
var percentagePoints = [];
var i = 0;
for( i = 0; i < mainInfo.content.length; i ++) {
timePoints.push(mainInfo.content[i].Time);
percentagePoints.push(mainInfo.content[i].Percentage);
}
$scope.labels = timePoints;
$scope.data = percentagePoints;
$scope.onClick = function (points, evt) {
console.log(points, evt);
};
});
json数据:
{
"records": [
{
"Id": "1",
"Time": "2015-07-25 08:00:00",
"Percentage": "60"
},
{
"Id": "2",
"Time": "2015-07-25 09:00:00",
"Percentage": "70"
},
{
"Id": "3",
"Time": "2015-07-25 10:00:00",
"Percentage": "80"
}
]
}
关于工厂 - 控制器通信,我只是从另一篇文章中提到解决方案:reference
答案 0 :(得分:7)
$ http.get返回一个承诺 - 您的问题是您立即返回“obj”,并且您的控制器在$ http.get承诺解析之前尝试访问数据。
像这样使用$ http(不需要使用$ q.defer(),如另一条评论所示):
<generator object comb at 0x106b2ceb0>
<generator object comb at 0x106b2cf00>
答案 1 :(得分:2)
试试这个
var obj = {content: []};
obj.$promise = $http.get('http://localhost/test.php').then(function(response) {
angular.copy(response.data.records, obj.content);
return response.data;
});
return obj;
您之前的方法不起作用的原因是您重新分配了content
的{{1}}属性,从而破坏了之前的任何引用。
这也是使用obj
工作的原因,因为保留了对$scope.foo = mainInfo
(通过obj
)的引用。
使用angular.copy
在填充数据时保留以前的引用。
这应该处理模板中的引用,该引用在mainInfo
承诺解析时(由于$http
触发摘要循环)得到更新。要访问控制器中的数据,请使用$http
属性
$promise
如果您与多个消费者(例如控制器)共享工厂,那么维护工厂内的数据是个好主意。他们可能都会引用$scope.foo = mainInfo.content;
mainInfo.$promise.then(function(data) {
// access data.records here
});
和mainInfo.content
,所有人都将访问相同的数据集。
答案 2 :(得分:0)
试试这个:
var app = angular.module("app", []);
app.factory('mainInfo', function($http) {
return {
getData: function() {
var deferred = $q.defer();
//the php will return json data below
$http.get('http://localhost/test.php').success(function(response){
deferred.resolve(response.records);});
return deferred.promise;
}
}
});
app.controller('Ctrl', function($scope, mainInfo){
mainInfo.getData().then(function(result) {
$scope.foo = result.content;
});
}) ;