【问题标题】:Load nested JSON array into select in Vue using computed properties使用计算属性将嵌套的 JSON 数组加载到 Vue 中的选择中
【发布时间】:2018-01-12 01:25:03
【问题描述】:

最初在我的 Vue 组件中,我有一系列嵌套的 if 语句,这些语句将通过 JSON 数据来确定是应该显示文本输入还是应该基于 has_selectable_value 选项的选择为真(选择显示)或假(文本输入显示),如果是选择,则循环遍历数据并输出相关选项。

我已经能够将其更改为计算语句,它几乎可以完成我需要它做的所有事情,除了显示选择选项的一件小事。

这里是Vue代码的相关部分:

<template v-else-if="searchtype == 9">
    <select v-for="service in selectableServices" class="form-control" v-model="searchvalue" required>
        <option value="">Select A Location</option>
        <option v-for="sl in selectableLocations" :value="sl.location_id">{{sl.name}}</option>
    </select>
    <input v-for="service in nonSelectableServices" class="form-control" v-model="searchvalue" placeholder="Enter Search Value" required>
</template>

当前的计算函数:

services: function () {   
    var ret = []
    this.countries.forEach(function(country) {
        country.states.forEach(function(state) {
            state.services.forEach(function(service) {
                ret.push(service)
            });
        });
    });

    return ret;               
},
selectableServices: function () {
    return this.services.filter(service => service.id == this.service && service.has_selectable_location);
},
nonSelectableServices: function () {
    return this.services.filter(service => service.id == this.service && !service.has_selectable_location);
},
selectableLocations: function () {
    // Filter one more level down
    return this.selectableServices.map(service => service.selectablelocations);
},

这也是我正在使用的 JSON 数据结构(我将其切回到这部分代码的相关部分):

[
    {
    "id": 1,
    "name": "Country Name",
    "states": [
        {
            "id": 1,
            "name": "State Name",
            "services": [
                    {
                    "id": 1,
                    "name": "Service Name",
                    "has_selectable_location": 1,
                    "selectablelocations": [
                            {
                                "id": 1,
                                "name": "Selectable Location A",
                            },
                        ]
                    }
                ]
            }
        ]
    }
]

使用适用于 Chrome 的 Vue 插件,我可以看到计算函数 selectableLocations 加载了一个包含各个位置的数组,但现有的 v-for 语句无法正常运行。相反,我仍然需要再下降一个级别,我可以通过添加一个额外的 v-for 循环来做到这一点,如下所示:

<template v-for="selectableLocationsList in selectableLocations" >
    <option v-for="sl in selectableLocationsList"  :value="sl.location_id">{{sl.name}}</option>
</template>

一切都正确显示,但我不确定这是否是最佳实践,因为我希望在计算函数中尽可能多地执行此操作,理想情况下只需要一个 v-for 语句。但如果这不可能,我理解,我可以保持原样。

提前谢谢你。

编辑:经过更多的测试和研究,我想出了这个代码,可以按我的意愿工作:

var formArray = []
var locationsArray = this.servicesArray.filter(service => service.id == this.service);

locationsArray.map(service => service.selectablelocations);

locationsArray.forEach(function(selectableLocations) {
    selectableLocations.selectablelocations.forEach(function(location) {
        formArray.push(location)
    });
});

return formArray;

有没有办法可以进一步重构它并使它更干净一些?

【问题讨论】:

  • 经过更多的研究和测试后,我提出了一些可以正常工作的代码,并且完成了将每个单独的位置添加到可以直接执行 v-for 函数的单个数组的工作,我已将其编辑到我的问题中,但如果可能的话,我想对其进行重构。

标签: javascript json vue.js vuejs2


【解决方案1】:

仅考虑您在 Edit 之后发布的代码,可以这样重构代码:

let formArray = [];

formArray = this.servicesArray
  .filter(service => service.id == this.service)
  .map(service => service.selectablelocations)
  .reduce((prev, curr) => prev.concat(curr))

return formArray

请注意,您使用的 map 没有做任何事情,因为 Array.prototype.map 只返回一个新数组,但您没有将它分配给任何东西。

【讨论】:

  • 您好 Kevlai22,感谢您抽出宝贵时间将此作为解决方案发布。我确实尝试了您的代码,但不幸的是它不起作用,选择中没有加载任何选项,在使用我的 Vue 扩展检查它之后,我可以看到 selectableLocations 是“未定义”。
  • 哦,我想这是因为“selectableLocations”中的“L”应该是小写的。已经更正了。
  • 就是这样,对不起,我应该自己了解。现在像魅力一样工作,我会将您的标记为正确答案。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 2018-03-19
相关资源
最近更新 更多