AngularJS嵌套对象数组路径

时间:2015-02-01 18:00:58

标签: javascript angularjs

我有一个工厂,它进入一个控制器,我试图从HTML页面上的那个显示器获取数据。但是,我无法指定对象的路径。

我的工厂:

app.factory('APIMethodService', function() {
  var Head = "api.example.com";
  return {
    apis: 
    [{
      accounts: [
        {
          v1: [
            {
              uri: Head+"/v1/accounts/",
              item1: "AccountNumber",
              item2: "MoneyInAccount"
            }],
            v2: [
            {
              uri: Head+"/v2/accounts/",
              item1: "AccountNumber",
              item2: "MoneyInAccount"
            }]
        }
      ],
      customers: [
        {
          v1: [
            {
              uri: Head+"/v1/customers/",
              item1: "CustomerName",
              item2: "CustomerID",
              item3: "CustomerEmail"
            }]
        }
      ]
    }]
  };
});

我的控制器:

app.controller('APIController', function($scope, APIMethodService) {
$scope.title = "API";
  $scope.apiList = APIMethodService;
  $scope.accountList = $scope.apiList.accounts.v1;
  $scope.accountList2 = $scope.apiList[0][0];
});

我的HTML

<div ng-controller="APIController">

<div id="api" class="row">
  <div class="col-xs-12">
    <div class="row" style="font-size:20px">
      {{title}} Page!
      <table class="table table-striped">
        <tr ng-repeat="api in apiList | orderBy:'uri' | filter:search">
           <td>{{api.uri}}</td>
           <td>{{api.item1}}</td>
           <td>{{api.item2}}</td>
        </tr>
      </table>
    </div>
  </div>
</div>

</div>

我得到的错误是关于控制器尝试解析我想要抓取的各个对象,例如帐户客户,然后是任何版本 v#,他们可能有。

所以它会说一些诸如

之类的东西
  

TypeError:无法读取属性&#39; v1&#39;未定义的

我只需要一些帮助来指定进入我工厂服务的正确途径。

2 个答案:

答案 0 :(得分:1)

你有一些问题。首先,您指的是从工厂返回的对象不正确。 APIMethodService是您正在注入的工厂,因此您需要首先引用该工厂返回的对象,如下所示:

APIMethodService.apis

这将为您提供整个JSON对象。

从那里开始,你的对象的其余部分由对象数组组成,所以引用'v1'对你没什么好处。您需要指定索引。如果你想要v1,你需要:

APIMethodService.apis[0].accounts[0].v1

这将为您提供v1数组,该数组也是一个对象数组。

客户将是:

APIMethodService.apis[0].customers[0].v1

答案 1 :(得分:0)

您遇到的第一个问题是工厂返回一个名为apis的单个属性的对象。所以基本上这个$scope.apiList.accounts.v1应该是$scope.apiList.apis.accounts.v1。由于点击(。)到apis是一个你必须使用索引的数组,所以这并不是全部,因为这不会起作用。在这种情况下,它将是$scope.apiList.apis[0],然后你可以.accounts[0].v1,它也是一个包含单个对象的数组。

现在,如果可以的话,我会建议您更改代表此数据结构的方式。

这就是你能做到的。

app.factory('APIMethodService', function() {
    var Head = "api.example.com";
    return {
        accounts: {
            v1: {
                uri: Head+"/v1/accounts/",
                items: ["AccountNumber","MoneyInAccount"]
            },
            v2: {
                ... // skipped for brevity
            }
        },
        customer: {
           ... // code skipped for brevity
        }
    };
});

如果您想要APIMethodService.accounts.v1.items[0]方法名称,那么只需点击您的APIMethodService对象,例如AccountNumber

然后可以像这样构建你的网址。

var baseUrl = APIMethodService.accounts.v1.uri; // 'api.example.com'
var url = baseUrl + APIMethodService.accounts.v1.items[0]; // 'AccountNumber'
// url = "api.example.com/v1/accounts/AccountNumber"
  

同样,这是你可以做到的一种方式,但这可以进一步增强。我提供的示例仅用于演示目的,这绝不是唯一的方法。

扩展收到的评论/问题后,您的服务(和数据表示)现在可能如下所示。

app.factory('APIMethodService', function() {
    var Head = "api.example.com";
    return {
        accounts: {
            v1: {
                uri: Head+"/v1/accounts/",
                items: [
                    {
                        name:'AccountNumber',
                        description:'Show the account number'
                    },
                    {
                        name:'AccountOwner',
                        description:'Show information about the owner of the account'
                    },
                    {
                        name:'MoneyInAccount',
                        description:'Show money in the Account'
                    }
                ]
            },
            v2: {
                ... // skipped for brevity
            }
        },
        customer: {
           ... // code skipped for brevity
        }
    };
});

// Get descriptions
var accountNumberDescription = APIMethodService.accounts.v1.items[0].description; // 'Show the account number'
var accountOwnerDescription = APIMethodService.accounts.v1.items[1].description; // 'Show information about the owner of the account'
var moneyInAccountDescription = APIMethodService.accounts.v1.items[2].description; // 'Show money in the Account'

通过使用具有此类属性的对象,您可以更轻松地理解您要执行的操作。对于带索引的数组,您必须知道或查看源代码才能看到正在发生的事情。在这里,有人查看您的代码,他们可以立即明白这是您正在获得的描述。