我已经拿起一个项目,我试图从服务返回一些数据到我的控制器。我一直在这里约12小时,并尝试了不同的方法。它们通常都会导致同样的“缺失数据”。AngularJS:控制器范围将不会与承诺同步
我使用$资源,而不是试图
- $ HTTP
- 把
$http.get
右控制器内部没有使用的承诺 - 服务作为实际服务(而不是工厂),而不返回
- 构建工厂一堆不同的方式返回各种格式的数据
- 使用setTimeout和$ apply
我觉得我现在已经是一个简单的,因为我可以得到它,一切我读过说这应该工作
angularjs-load-data-from-service
angular-controller-cant-get-data-from-service
angularjs-promises-not-firing-when-returned-from-a-service
angularjs-promise-not-resolving-properly
这些链接只是从今天起。
我认为有可能是一个$范围的问题,因为在过去我见过$范围时,多个控制器习惯没有得到数据,但是该网站仅仅声明中的index.html控制器为<body ng-app="myApp" ng-controller="BodyCtrl">
设置。主要app.js使用状态(从UI路由器我相信)是这样的...
.state('app.view', {
url: '/view',
templateUrl: 'views/view.tpl.html',
controller: 'MyCtrl'
})
到控制器连接到不同的页面。此外,该网站还有一些其他控制器从服务器获取数据,我首先将其作为模板进行了查看,但是,数据和回报比我想要的要复杂得多。尽管如此,控制器正在访问从服务提供的数据。他们都使用$资源,这是我从这个问题开始的。我一直坚持使用$ http,因为它应该的工作,并且我想在我进入更高级别之前使用它。另外,我只需要从端点获得GET,所以感觉$资源是过量的。
服务
.factory('MyService', ['$http', '$q', '$rootScope', function ($http, $q, $rootScope) {
var defer = $q.defer();
var factory = {};
factory.all = function() {
$http({method: 'GET', url: 'http://URLtoJSONEndpoint'}).
success(function (data, status, headers, config) {
console.log('data success', data);
defer.resolve(data);
}).
error(function (data, status, headers, config) {
console.log('data error');
defer.reject(data);
});
return defer.promise;
};
return factory;
}]);
控制器
.controller('MyCtrl', ['$scope', '$state', '$stateParams', '$rootScope', 'MyService', '$q', function ($scope, $state, $stateParams, $rootScope, MyService, $q) {
...
...
$scope.data = null;
$scope.object = MyService;
$scope.promise = MyService.all();
MyService.all().then(function (data) {
$scope.data = data;
console.log("data in promise", $scope.data);
})
console.log("data", $scope.data);
console.log("object", $scope.object);
console.log("promise", $scope.promise);
$http({method: 'GET', url: 'http://URL'}).
success(function (data, status, headers, config) {
$scope.data = data;
console.log('data success in ctrl', data);
}).
error(function (data, status, headers, config) {
console.log('data error');
});
console.log("data after ctrl", $scope.data);
angular.forEach($scope.data, function (item) {
// stuff that I need $scope.data for
}
控制台日志
所以这是我的控制台日志,我可以在所以睦得到h,只是不是实际的数据!这是我需要的。我甚至疯了,并延长我的.then(function (data) {
捕获控制器中需要$scope.data
的所有功能。那是一列火车残骸。
***data null***
object Object {all: function}
promise Object {then: function, catch: function, finally: function}
***data success after ctrl null***
data success in ctrl Array[143]
data success Array[143]
data in promise Array[143]
data success Array[143]
据我所知,这应该工作,但我不知道还有什么地方的问题都可以!也许我不明白承诺如何工作或解决。我之前在另一个项目中使用过Angular,但我在开始时就已经了解它,并了解它是如何组合在一起的。这个项目的结构不同,感觉更加混乱。我想简化它,但我甚至无法得到一些简单的数据返回!
我很感激任何帮助/反馈,您可以提供确定为什么这不起作用,谢谢!
编辑:所以问题是,为什么console.log("data", $scope.data)
回到空/承诺之前?
有点控制器后面我有这个
angular.forEach($scope.data, function (item) {
// stuff
}
,它似乎并没有能够访问的数据。
EDIT2:我已经添加了我所用的控制器内的$http.get
,与它和真正的forEach控制台日志沿着我需要$scope.data
为
EDIT3:
更新服务
.service('MyService', ['$http', function ($http) {
function all() {
return $http({
url: 'http://URL',
method: 'GET'
});
}
return {
all: all
}
}]);
更新控制器
MyService.all().success(function (data) {
$scope.data = data;
angular.forEach($scope.data, function (item) {
// Turn date value into timestamp, which is needed by NVD3 for mapping dates
var visitDate = new Date(item.testDate).getTime();
switch (item.Class) {
case "TEST":
testData.push(
[
visitDate,
item.Total
]
);
}
});
console.log("test Data in success", testData);
});
$scope.testData = [
{
"key": "Test",
"values": testData
}
];
所以$scope.testData
需要在视图(nvd3图表)中使用,它不会获取数据。
SOLUTION
MyService.all().success(function (data) {
$scope.data = data;
angular.forEach($scope.data, function (item) {
// Turn date value into timestamp, which is needed by NVD3 for mapping dates
var visitDate = new Date(item.testDate).getTime();
switch (item.Class) {
case "TEST":
testData.push(
[
visitDate,
item.Total
]
);
}
});
console.log("test Data in success", testData);
$scope.testData = [
{
"key": "Test",
"values": testData
}
];
});
所以你的问题是,为什么'的console.log(“数据”,$ scope.data); // =>数据null'?如果是,那么可能是因为在异步调用完成之前执行日志。Sidenote对'MyService.all();'的两次调用实际上会触发两个请求。我认为第一个没有必要。 – Yoshi
是的,确切!感谢您指出这一点,不是很清楚 – mykepwnage
我会开始通过让它在你的控制器内工作,所以成功做$ scope.data = data;当您可以看到呼叫成功工作时,开始使用服务重新定位,认为您正在增加复杂性。 $ http已经返回一个承诺,所以你不需要使用另一个承诺。 https://docs.angularjs.org/api/ng/service/$http – LightningShield