首页 > 解决方案 > 在选择中获取键的名称

问题描述

我正在尝试从 JSON 填充选择元素,但 JSON 的格式设置为密钥包含有价值的信息。我无法控制数据格式。

我正在尝试遍历 JSON 并获取数组中顶级对象的键名。问题是,因为它是一个对象,我似乎不能只抓住它的名字—— Object.keys() 由于作用域,它在 ng-options 中不起作用。

我已经尝试了以下许多变化,但没有运气。

<select ng-model="$ctrl.vals"
        ng-options="val as key for (key, val) in $ctrl.data"
        ng-change="$ctrl.onChange()" name="{{$ctrl.name}}"
        size="{{$ctrl.data.length}}" multiple>
</select>

上面返回“0”,因为它被格式化为 0: [object object]。我能得到的最接近的是 [Object Object] 返回,但我想要那个对象的键,但不知道如何得到它。

我有这样格式化的数据(示例数据,不是真实的):

{
"Games": [{
    "Name": "Warhammer 40k 8th Edition",
    "Factions": [{
        "Space Marines": {
            "Units": [{
                "Name": "Primaris Space Marine Captain",
                "Number": 1,
                "Cost": -1,
                "Ability": "When captain enters play you win",
                "AddOns": [{
                    "Name": "My AddOn",
                    "Cost": 0,
                    "Text": "Add an extra Captain",
                    "IsSelected": false
                }],
                "Gear": [{
                    "Name": "Frag Grenade",
                    "Cost": 0
                }]

            }]
        }
        }]
    }]
}

在上述 JSON 的上下文中,我想传入 Factions 并查看文本“Space Marines”作为选项。我错过了什么?

标签: javascriptangularjs

解决方案


如果$ctrl.data在您的代码段中引用了"Factions"您编写的属性值,那么ng-options您使用的表达式不兼容(即... for (key, value) in ...表单需要$ctrl.data是一个对象,但它不是)。

随后,您应该使用数组表达式形式 for ng-options,然后您可以提供额外的函数来删除用户选择特定选项时将绑定的标签和模型。

以下是您可以采取的方法:

angular
  .module('app', [])
  .controller('ctrl', function () {
    const $ctrl = this;
    $ctrl.modelFor = function (obj) {
      const [key] = Object.keys(obj);
      return key ? obj[key] : null;
    };
    $ctrl.labelFor = function (obj) {
      const [key] = Object.keys(obj);
      return key;
    };
    $ctrl.data = [{
      "Space Marines": {
        "Units": [{
          "Name": "Primaris Space Marine Captain",
          "Number": 1,
          "Cost": -1,
          "Ability": "When captain enters play you win",
          "AddOns": [{
            "Name": "My AddOn",
            "Cost": 0,
            "Text": "Add an extra Captain",
            "IsSelected": false
          }],
          "Gear": [{
            "Name": "Frag Grenade",
            "Cost": 0
          }]
        }]
      }
    }];
  });
<div
  ng-app="app"
  ng-controller="ctrl as $ctrl">
  <select
    ng-model="$ctrl.vals"
    ng-options="$ctrl.modelFor(obj) as $ctrl.labelFor(obj) for obj in $ctrl.data"></select>
  <pre>{{ $ctrl.vals }}</pre>
</div>
<script src="https://unpkg.com/angular@1.7.8/angular.min.js"></script>

顺便说一句,您的数据看起来有点奇怪。如果每个项目$ctrl.data可以有多个键,那么这种方法将任意选择第一个(即在迭代键时不能保证排序)。


推荐阅读