I am using a factory in angular.js and $http.get method to grab and process JSON data. The JSON data seems successfully parsed into factory, but I have problem access property of this JSON data.
我用的是有角的工厂。js和http。获取获取和处理JSON数据的方法。JSON数据似乎成功地解析为工厂,但我有这个JSON数据的问题访问属性。
Here is my js code:
以下是我的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;
}) ;
Now if I try to access foo within Ctrl
controller, the webpage will display no data:<div ng-controller="Ctrl">Controller: {{foo}}</div>
However, if I change to $scope.foo = mainInfo
in the Ctrl
, then the webpage will display correctly the JSON data.
现在,如果我尝试在Ctrl controller中访问foo,页面将不会显示任何数据:
May I know what is the proper way to access mainInfo.content
property in Ctrl
controller?
我想知道访问mainInfo的正确方法是什么。内容属性在Ctrl控制器中?
The reason why I need to access JSON property is because I need to pre-process the data. I intend to use these data in a Chart, as in below controller. Currently this controller is not working either, because I have the same problem accessing JSON property as in the Ctrl
controller.
我需要访问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);
};
});
The json data:
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"
}
]
}
With regards to the factory-controller communication, I am just referring the solution from another post: reference
关于工厂-控制器通信,我只是引用了另一篇文章中的解决方案:reference
3 个解决方案
#1
7
$http.get returns a promise -- your problem is that you are returning "obj" immediately, and your controller tries to access the data before the $http.get promise is resolved.
美元http。get返回一个承诺——您的问题是您正在立即返回“obj”,并且您的控制器试图在$http之前访问数据。承诺是解决。
use $http like so (no need to use $q.defer() as shown in the other comment):
使用$http like so(不需要使用$q. delay(),如其他注释所示):
var app = angular.module("app", []);
app.factory('mainInfo', function($http) {
var getRecordsPromise = $http.get('http://localhost/test.php').then(function(response){
//whatever is returned here will be accessible in the .then that is chained
return response.data.records;
});
return {
getRecords: getRecordsPromise
};
});
app.controller('Ctrl', function($scope, mainInfo){
mainInfo.getRecords.then(function (records) {
$scope.foo = records;
});
}) ;
#2
2
Try this instead
试试这个相反
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;
The reason your former method didn't work was because you were re-assigning the content
property of obj
, thus destroying any previous references.
您以前的方法不起作用的原因是您重新分配了obj的内容属性,从而破坏了以前的引用。
This is also why using $scope.foo = mainInfo
worked because the reference to obj
(via mainInfo
) was maintained.
这也是为什么要使用$scope。foo = mainInfo工作,因为对obj(通过mainInfo)的引用被维护。
Using angular.copy
maintains the previous reference whilst populating the data.
使用角。复制在填充数据时维护先前的引用。
That should take care of references in the template that get updated when the $http
promise resolves (due to $http
triggering a digest cycle). For accessing the data in your controller, use the $promise
property
当$http承诺解决时(由于$http触发摘要周期),模板中的引用将被更新,这应该会得到注意。要访问控制器中的数据,请使用$promise属性
$scope.foo = mainInfo.content;
mainInfo.$promise.then(function(data) {
// access data.records here
});
Maintaining the data inside your factory is a good idea if you share your factory with multiple consumers (eg controllers). They may all reference mainInfo.content
and mainInfo.$promise
and all will be accessing the same data set.
如果您将工厂与多个使用者(如控制器)共享,那么在工厂内部维护数据是一个好主意。他们都可以参考主信息。内容和mainInfo。$promise和all将访问相同的数据集。
#3
0
Try this:
试试这个:
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;
});
}) ;
#1
7
$http.get returns a promise -- your problem is that you are returning "obj" immediately, and your controller tries to access the data before the $http.get promise is resolved.
美元http。get返回一个承诺——您的问题是您正在立即返回“obj”,并且您的控制器试图在$http之前访问数据。承诺是解决。
use $http like so (no need to use $q.defer() as shown in the other comment):
使用$http like so(不需要使用$q. delay(),如其他注释所示):
var app = angular.module("app", []);
app.factory('mainInfo', function($http) {
var getRecordsPromise = $http.get('http://localhost/test.php').then(function(response){
//whatever is returned here will be accessible in the .then that is chained
return response.data.records;
});
return {
getRecords: getRecordsPromise
};
});
app.controller('Ctrl', function($scope, mainInfo){
mainInfo.getRecords.then(function (records) {
$scope.foo = records;
});
}) ;
#2
2
Try this instead
试试这个相反
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;
The reason your former method didn't work was because you were re-assigning the content
property of obj
, thus destroying any previous references.
您以前的方法不起作用的原因是您重新分配了obj的内容属性,从而破坏了以前的引用。
This is also why using $scope.foo = mainInfo
worked because the reference to obj
(via mainInfo
) was maintained.
这也是为什么要使用$scope。foo = mainInfo工作,因为对obj(通过mainInfo)的引用被维护。
Using angular.copy
maintains the previous reference whilst populating the data.
使用角。复制在填充数据时维护先前的引用。
That should take care of references in the template that get updated when the $http
promise resolves (due to $http
triggering a digest cycle). For accessing the data in your controller, use the $promise
property
当$http承诺解决时(由于$http触发摘要周期),模板中的引用将被更新,这应该会得到注意。要访问控制器中的数据,请使用$promise属性
$scope.foo = mainInfo.content;
mainInfo.$promise.then(function(data) {
// access data.records here
});
Maintaining the data inside your factory is a good idea if you share your factory with multiple consumers (eg controllers). They may all reference mainInfo.content
and mainInfo.$promise
and all will be accessing the same data set.
如果您将工厂与多个使用者(如控制器)共享,那么在工厂内部维护数据是一个好主意。他们都可以参考主信息。内容和mainInfo。$promise和all将访问相同的数据集。
#3
0
Try this:
试试这个:
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;
});
}) ;