简体   繁体   English

从工厂角度访问json嵌套数组

[英]access json nested array from factory angular

in my angular app I use a factory which get json data and pass it to a controller. 在我的角度应用程序中,我使用工厂获取json数据并将其传递给控制器​​。 it is working for me if I use simple json array but fails in a nested array in case of a simple json file I have this structure 如果我使用简单的json数组但是在一个简单的json文件的情况下在嵌套数组中失败,它对我有用我有这个结构

[
          {
            "name": "bond_1",
            "profession": "Programmer",
            "hometown": "St Louis, MO"
          },
          {
            "name": "bond_2",
            "profession": "Salesman",
            "hometown": "Denver, CO"
          },
          {
            "name": "bond_3",
            "profession": "CEO",
            "hometown": "San Francisco, CA"
          }
]

my factory is this 我的工厂就是这个

.factory('Topology', function ($http){
 var data = [];
 return{
    get: function(){
        if (data.length == 0){
           $http.get("data.json") 
           .success(function (response){
               for(var i=0, ii=response.length; i<ii; i++){
                   data.push(response [i]);
               }
           });
        }
        return data;
    },
  }
});

and my controller is this 而我的控制器就是这个

var installerControllers =angular.module('installerControllers', []);
installerControllers.controller('stageThreeCtrl', function ($scope,   Topology) {
       $scope.bonds=Topology.get();
})

now it all working fine and I can view the data when I doing ng-repeat on it from the view 现在一切正常,我可以在视图中对其进行ng-repeat时查看数据

but i need instead of the simple json structure use a nested array which looks like this 但我需要使用一个看起来像这样的嵌套数组而不是简单的json结构

{
"bonds":[
        {
        "name": "Alex",
        "profession": "Programmer",
        "hometown": "St Louis, MO"
      },
      {
        "name": "David",
        "profession": "Salesman",
        "hometown": "Denver, CO"
      },
      {
        "name": "Laura",
        "profession": "CEO",
        "hometown": "San Francisco, CA"
      }
],
"networks":[
      {
      "name": "test",
      "all_hosts": "false",
      "IP_Version": "IPV4",
      "IP address": "10.10.10.10",
      "IPV net mask": "255.255.255.0",
      "Interface": "bond 0",
      "VLAN TAG": "4001",
      "Description": "some custom description"
    }
  ]
}

now I am trying to call for one of the objects from the controller in this way 现在我试图以这种方式从控制器中调用其中一个对象

var installerControllers =angular.module('installerControllers', []);
installerControllers.controller('stageThreeCtrl', function ($scope, Topology) {
   var data=Topology.get();
   $scope.bonds=data.bonds;  
})

but it is not working and I got in the console.log an empty array 但它没有工作,我在console.log中得到一个空数组

your help will be very appreciated 非常感谢您的帮助

Your problem is NOT an asynchronous problem, you simply aren't referencing your new data format properly. 您的问题不是异步问题,您只是没有正确引用新的数据格式。 I've substituted the $http call with a $timeout since I don't have a server to test against that returns your data. 我用$timeout替换了$http调用,因为我没有要测试的服务器返回你的数据。 Since your data format has changed, you need to change the way you're referencing it in the factory, controller, and view. 由于您的数据格式已更改,因此您需要更改在工厂,控制器和视图中引用它的方式。

 var app = angular.module('app', []).factory('Topology', function ($timeout){ var data = {}; // no longer an array return{ get: function(){ if (!data.bonds){ $timeout(function () { data.bonds = [{name: 'Hello World!'}]; // this would be response.bonds data.networks = [{name: 'Hello World!'}]; // this would be response.networks }, 2000); } return data; }, } }).controller('stageThreeCtrl', function ($scope, Topology) { var data=Topology.get(); $scope.data = data; // renamed to data }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="app"> <p>wait 2 seconds...</p> <ul ng-controller="stageThreeCtrl"> <li ng-repeat="bond in data.bonds">{{bond.name}}</li> <!-- using data.bonds --> </ul> </div> 


A better alternative would be to do some minor restructuring to instead take advantage of the promise returned from $http . 一个更好的选择是做一些小的重组,而不是利用$http返回的承诺。

var app = angular.module('app', []).factory('Topology', function ($http){
  var promise;

  return{
    get: function(){
        if (!promise){
          promise = $http.get("data.json");
        }
        return promise;
    },
  }
}).controller('stageThreeCtrl', function ($scope, Topology) {
   Topology.get().then(function (response) {
     $scope.bonds = response.data.bonds;
   });
});
// your original view should now work

Try this 尝试这个

   angular.module('app', []).factory('Topology', function ($http,$q){
 return{
    get: function(){
        var d = $q.defer();
           $http.get("data.json") 
           .success(function (response){ 
             console.log(response)
               d.resolve(response);
           });
        return d.promise; 
    },
  }
}).controller('stageThreeCtrl', function ($scope, Topology) {
  Topology.get().then(function (response) {

    $scope.bonds = response.bonds;  
  });
});

Try 尝试

Topology.get().then(function (data) {
    $scope.bonds=data.bonds;
});

As pointed out in the comments, I didn't notice that the get function wasn't returning a promise. 正如评论中指出的那样,我没有注意到get函数没有返回一个promise。

To return a promise, the $http API is based on the deferred/promise APIs exposed by the $q service, so just use the code below in the get function with the factory (service). 要返回一个promise,$ http API基于$ q服务公开的deferred / promise API,所以只需在get函数中使用下面的代码和factory(service)。

return $http.get('data.json');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM