似乎无法访问json数据的特定元素

时间:2016-07-13 20:27:20

标签: javascript angularjs json

我有一个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函数之外使用它。

之前有人说过“这是不可能的”,其他人会同意吗?

2 个答案:

答案 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语句被激活时,我可以删除等待指示符。