【问题标题】:Create grouped table with array of objects in Javascript在Javascript中使用对象数组创建分组表
【发布时间】:2019-08-21 03:36:34
【问题描述】:

我找到了一些似乎很接近的答案,但无法让它们发挥作用,所以如果有人有一个答案,如果这是重复的,他们想指出我,我很乐意去看看。我有一个看起来像这个例子的对象数组:

[
    {Type:0001,Build:"light",Weight:1,Volume:1},
    {Type:0001,Build:"light",Weight:1,Volume:1},
    {Type:0001,Build:"heavy",Weight:4,Volume:1},
    {Type:0002,Build:"light",Weight:2,Volume:3},
    {Type:0002,Build:"light",Weight:2,Volume:3},
    {Type:0003,Build:"light",Weight:1,Volume:1},
    {Type:0003,Build:"light",Weight:1,Volume:1},
    {Type:0003,Build:"heavy",Weight:5,Volume:3},
    {Type:0004,Build:"light",Weight:1,Volume:1}
]

我是用这个创建的:

let parseString = str => {
    let pairs = str.split(',');
    let obj = {};
    pairs.forEach(pair => {
        pair = pair.split(':');
        obj[pair[0]] = pair[1];
    });
    return obj;
};

我能够根据需要将字符串解析为第一个代码块中的数组。这不太重要,只是想指出一个由 for 循环在某些字符串上创建的变量。

该数组在另一个函数中使用 push 作为“buildObjects”返回。我可以在为前端显示构建的 HTML 文件中访问 buildObjects。我们使用 Vue,但仅用于显示。我们拥有的查看器组合了输入的 js、HTML、CSS,然后组合了一个缩小的 Vue 文件以呈现 HTML 输出。但是,我不能使用普通的 Vue 组件、方法等...

我需要做的是把上面的数据变成这样的表格:

Type    Build   Count   Weight  Volume
0001                            
        light   2       2       2
        heavy   1       4       1       
0002                    1       1
        light   2       4       6
0003                
        light   2       3       2
        heavy   1       5       3
0004
        light   1       1       1   

我必须使用 Vue 进行前端演示,并尝试像这样使用 v-for 和行跨度:

<tr v-for="buildObject in buildObjects">
    <td rowspan="4">{{buildObject.Type}}</td>
    <td>{{buildObject.Build}}</td>
    <td>{{buildObject.Count}}</td>
    <td>{{buildObject.Volume}}</td>                            
</tr>

但这不起作用,这是有道理的。

我真正需要的是一个可以帮助我使用 javascript 的人,请注意,不是组件、计算组件等,只是 javascript,来构建像上面那样的表格,并且还可以帮助处理其中的 HTML Vue 部分.我很困。我已经走到这一步了。我有一个从这个 JSON 数据构建的表格,它带有一些时髦的格式,需要在 javascript 中进行大量操作才能获得上面的数组。我快完成了,只是……卡住了。感谢所有帮助。

【问题讨论】:

  • 你有没有将buildObjects 初始化为组件data 中的一个空数组?模板中引用的任何内容都必须在组件脚本中声明。
  • @Josef7 是的 buildObjects 被初始化为一个空数组。它正在正确创建并按问题中发布的方式返回。
  • 我不确定您所说的“使用 Vue 进行前端演示”而不使用组件和计算属性是什么意思。您只是将它用于模板,即访问模板中的变量吗?有像 Thymeleaf 这样的模板引擎可以做到这一点。你使用的是什么引擎,需要一个 Vue 模板而不是一个 Vue 组件?
  • @Josef7 一些我无法访问的专有引擎。我所知道的是我使用 javascript 返回数据以使用,然后在模板上使用 Vue。这是我提供帮助的项目的一部分,因为我比其他团队成员拥有更多的 javascript 经验,但我被困住了。
  • 好吧,听起来你只需要用 JavaScript 编写它。 Vue 不像 jQuery 或 Bootstrap,你只需要包含源代码就可以了。您的脚本必须与 Vue 代码一起预编译和注入。如果你不能使用 Vue 组件,那听起来好像不会发生。不知道为什么会有这样的限制。

标签: javascript arrays vue.js


【解决方案1】:

我对 vue 不熟悉,但您必须更改 buildObjects 函数以检索如下列表:

items = [
{Type:"0001",Build:"light",Weight:1,Volume:1,rowspan:3},
{Type:"0001",Build:"light",Weight:1,Volume:1},
{Type:"0001",Build:"heavy",Weight:4,Volume:1},
{Type:"0002",Build:"light",Weight:2,Volume:3,rowspan:2},
{Type:"0002",Build:"light",Weight:2,Volume:3},
{Type:"0003",Build:"light",Weight:1,Volume:1,rowspan:3},
{Type:"0003",Build:"light",Weight:1,Volume:1},
{Type:"0003",Build:"heavy",Weight:5,Volume:3},
{Type:"0004",Build:"light",Weight:1,Volume:1,rowspan:1}
];

并将您的 html 代码更改为等效于以下角度代码

<tr *ngFor="let item of items">
    <td  *ngIf="item.rowspan" [attr.rowspan]="item.rowspan" >{{item.Type}}</td>
    <td>{{item.Build}}</td>
    <td>{{item.Weight}}</td>
    <td>{{item.Volume}}</td>                            
</tr>

PS:列表应该排序

【讨论】:

    【解决方案2】:

    很难理解您是否可以访问 Vue 脚本。当您在前端使用 Vue 时,您应该能够通过计算属性更改数据结构,然后对其进行迭代。

    您尝试实现的一个实施示例:

    refactoredBuildObjects() {
        return Array.from(
            this.buildObjects.reduce((t, v) => {
                if (t.has(v.Type)) {
                    const item = t.get(v.Type)
    
                    if (item.Entries.has(v.Build)) {
                        const entry = item.Entries.get(v.Build)
                        entry.Weight +=  v.Weight
                        entry.Volume += v.Volume
                        entry.Count++
    
                        item.Entries.set(v.Build, entry)
                    }
                    else {
                        item.Entries.set(v.Build, { Build: v.Build, Weight: v.Weight, Volume: v.Volume, Count: 1 })
                    }
    
                    t.set(v.Type, item)
                }
                else {
                    t.set(v.Type, {Type: v.Type, Entries: new Map([[v.Build, { Build: v.Build, Weight: v.Weight, Volume: v.Volume, Count: 1 }]]) })
                }
    
                return t;
            }, new Map()).values()
        ).map(item => {
            item.Entries = Array.from(item.Entries.values())
            return item
        })
    }
    

    我创建了一个Fiddle 以进行完整的实施。

    【讨论】:

      猜你喜欢
      • 2015-02-25
      • 1970-01-01
      • 2015-10-18
      • 2023-02-02
      • 2019-04-05
      • 2012-04-01
      • 2010-10-04
      • 2012-03-06
      • 1970-01-01
      相关资源
      最近更新 更多