我有一个Angular应用程序,其中包含一个访问服务的控制器。我有服务正确地将数据发送回我的控制器,但在.then
函数中我似乎无法访问json数据的特定元素。
控制器(摘要)
vm.getData = function(eventid) {
monitorData.requestEvent(eventid)
.then(function(data) {
// console.log(data);
vm.event.id = data.id;
})
.catch(function(e) {
console.log("Error");
});
return false;
};
vm.getData($routeParams.eventid);
示例数据
{
id: "123456",
type: "pokemon",
time: "July 13, 2016 at 04:00 PM Eastern Daylight Time",
oneURL: "www.junk1.com",
twoURL: "www.junk2.com",
threeURL: "www.junk3.com",
phone: "1 (555) 765-4321",
notes: "some junk here",
}
如果我console.log(data);
,它会打印到我的浏览器控制台。但我尝试设置一个等于data
的变量,然后将其打印到函数外部,但它不会。我也无法访问json对象的任何特定部分。
我确信这有一个简单的解释,但我似乎无法在任何地方找到它。
... 修改(添加服务代码)
(function() {
angular
.module('monitorApp')
.service('monitorData', monitorData);
monitorData.$inject = ['$http'];
function monitorData($http) {
var requestEvent = function(eventid) {
return $http.get('/api/event/' + eventid);
};
return {
requestEvent : requestEvent,
};
}
})();
... 编辑以澄清
由于用户之前的混淆,让我试着更清楚:在上面的控制器代码中你会看到
.then(function(data) {
// console.log(data);
vm.event.id = data.id;
})
在此代码段中,您会看到data
。该数据包含我上面列出的对象(示例数据)。
我的问题是,是否有某种方法可以进一步访问id, type, time, ... phone, notes
。我可以console.log(data)
它将在控制台中打印出对象(用于测试目的),但是我需要访问对象中的每个项目并在整个vm.getData
函数之外使用它。
之前有人说过“这是不可能的”,其他人会同意吗?
答案 0 :(得分:0)
根据我的理解,此控制器绑定到特定的资源视图(某些事件的详细信息)。
以下是实现愿望的两种方法:
在状态定义中使用resolve
子句(我认为这更优雅):
//Note: this is assuming ui-router, but also possible in ng-route.
.state('event.details', {
url: '/event/:id',
controller: ...
templateUrl: ...
resolve: {
event: function($stateParams, $state, monitorData){
//Will wait for this GET request to finish before loading the view
//You can then inject event into the controller as any service
//like so: .controller('eventCtrl', function(event){}...)
return monitorData.requestEvent($stateParams.id)
.catch(function(e){
//Something went wrong, redirect the user and notify them
$state.go('error', {error: e});
});
}
}
});
缓存承诺的结果:
var promise;
vm.getData = function(eventid) {
promise = monitorData.requestEvent(eventid)
.then(function(data) {
// console.log(data);
vm.event.id = data.id;
})
.catch(function(e) {
console.log("Error");
});
return false;
};
//Wherever you need the results of the promise just use the cached version
//Note: this might fail if you depend on this promise when your controller first loads.
promise.then(function(data){
//data.id available here
});
答案 1 :(得分:0)
解决方法是service
。问题是我正在返回以下内容:
(WRONG)
return $http.get('/api/event/' + eventid);
所以我改为使用.then
函数来链接承诺。当我应该回来data
时,我也会回来response.data
。请参阅以下代码:
(RIGHT)
return $http.get('/api/event/' + eventid).then(function(response) {
return response.data;
});
最终 服务:
(function() {
angular
.module('monitorApp')
.service('monitorData', monitorData);
monitorData.$inject = ['$http'];
function monitorData($http) {
var requestEvent = function(eventid) {
return $http.get('/api/event/' + eventid).then(function(response) {
return response.data;
});
};
return {
requestEvent : requestEvent,
};
}
})();
最终 控制器
vm.getData = function(eventid) {
monitorData.requestEvent(eventid)
.then(function(data) {
console.log(data.id);
})
.catch(function(e) {
console.log("Error");
});
return false;
};
vm.getData($routeParams.eventid);
<强>结论强>
所以现在我可以使用controller
和一系列承诺在我的service
中成功拨打api电话。当我将.then
添加到返回return response.data;
的return语句时,解决方案就到了。我认为如果api调用需要永远,这应该仍然有效。我可以在monitorData.requestEvent(eventid)
之前在我的控制器代码中轻松添加一个等待指示符,然后当.then
语句被激活时,我可以删除等待指示符。