我已經拿起一個項目,我試圖從服務返回一些數據到我的控制器。我一直在這裏約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