首页 > 解决方案 > 如何从html获取输入值数组到JS

问题描述

我在 salesforce.stackexchange.com 上发布了同样的问题,下面是链接

https://salesforce.stackexchange.com/questions/283596/how-to-fetch-input-field-value-in-js-in-lwc?noredirect=1#comment426016_283596

但是在评论中人们认为这与salesforce没有太大关系,它更多的是Javascript,所以我在这里发布相同的内容,请从html和js的角度看一下并提出建议。

HTML 语法似乎不同,因为它是 salesoforce 的闪电网络组件而不是 angular,还请帮助我理解 angular 中的相同行为,我将在 salesforce 中相应地做

在下面的 html 代码中,我正在迭代 2 个列表 linItemData(11 条记录)和 studyData(20 条记录)

<table class="slds-table slds-table_cell-buffer slds-table_bordered">
          <thead>
            <tr class="slds-line-height_reset">
              <template if:true={studyData}>
                <template for:each={studyData} for:item="sData">
                  <th key={sData}>
                    <div class="tablename slds-p-bottom_medium"></div>{sData.Visit_Name__c}
                  </th>
                </template>
              </template>
            </tr>
          </thead>
          <tbody>
            <template if:true={lineItemData}>
              <template for:each={lineItemData} for:item="sLineItem">
                <tr key={sLineItem}>
                  <template for:each={studyData} for:item="sData">
                    <td key={sData.Id}>
                      <lightning-input variant="label-hidden" class="fieldSize" type="number" step="0.01"
                        label="visitValue" data-key={sData.Id} onchange={visitValueChange} placeholder="00.00">
                      </lightning-input>
                    </td>
                  </template>
                </tr>
              </template>
            </template>
          </tbody>
        </table>

我得到了一个预期的结果,其中包含 UI 上所有必需的输入字段,如下所示:

在此处输入图像描述

现在我需要获取所有 v20 的输入值,例如 v1(第一列名称)应该有 11 个输入记录的数组。

JS如下:

visitValueChange(event) {
    this.studyData
        .find(item => item.Id === event.currentTarget.dataset.key)
        .visitValue = event.target.value;
}

我已经尽我所能,但 visitValue 只能保存 1 个最近的值,例如,如果我在第一个输入字段添加 1,在第二个输入字段添加两个,在第三个添加三个等等,然后我点击一个调用 JS 函数的按钮查看 studyData 数组,但它只有最近的值,即 3 不是所有输入的 1,2 和 3 值,并且要求在所有列的所有 11 个输入字段上添加一个包含所有输入值的数组。请帮助我提出任何解决方法。

标签: javascripthtmlarrayssalesforce-lightning

解决方案


你有两个问题:

  • 数据的设计方式
  • 将输入与正确的记录相关联

数据模型

根据您的上下文,您可以这样说:

  • 每行是一个记录,列是记录的属性(col1,col2,...)
  • 每列是一条记录,行是记录的属性(row1,row2,...)
  • 每个单元格都是一个记录,其 ID 为x_y(1_1, 1_2, ...)

我可能会推荐选项 1,因为它是最常见的表示。

这意味着您必须准备/创建这样的记录:

const myRecords = [
    { 
        id: 1,
        col1: 0,
        col2: 0,
        ...
    }, {
        id: 2,
        col1: 0,
        col2: 0,
        ...
    }
]

将输入链接到正确的记录

使用LWC 数据表来创建您的表。然后,您可以使用自定义数据类型获得所需的内容。这将允许使用正确设计的记录(一行一行,每列是一个属性)而无需任何转换。

使用提供的 HTML 显示

不幸的是,Salesforce 中存在一些限制(使用您提供的 HTML),因此您需要将记录转换为此。

const myRecords = [
    { 
        id: 1,
        columns: [
            { id: 1, value: 0 },
            { id: 2, value: 0 }
            ...
        ]
    }, {
        id: 2,
        columns: [
            { id: 1, value: 0 },
            { id: 2, value: 0 }
            ...
        ]
    }
]

这将允许它工作

import {
  LightningElement,
  track
} from 'lwc';

export default class App extends LightningElement {
  columns = [{
      id: '1',
      name: 'v1'
    },
    {
      id: '2',
      name: 'v2'
    },
    {
      id: '3',
      name: 'v3'
    },
    {
      id: '4',
      name: 'v4'
    },
    {
      id: '5',
      name: 'v5'
    },
  ]

  records = [{
      id: '1',
      columns: [{
          id: '1',
          value: 0
        },
        {
          id: '2',
          value: 0
        },
        {
          id: '3',
          value: 0
        },
        {
          id: '4',
          value: 0
        },
        {
          id: '5',
          value: 0
        },
      ]
    },
    {
      id: '2',
      columns: [{
          id: '1',
          value: 0
        },
        {
          id: '2',
          value: 0
        },
        {
          id: '3',
          value: 0
        },
        {
          id: '4',
          value: 0
        },
        {
          id: '5',
          value: 0
        },
      ]
    }
  ]

  visitValueChange(event) {
    const recordId = event.target.dataset.recordId
    const columnId = event.target.dataset.columnId
    const value = event.target.value

    const record = this.records.find(record => record.id === recordId)
    const column = record.columns.find(column => column.id === columnId)

    column.value = value
  }
}
<template>
  <table class="slds-table slds-table_cell-buffer slds-table_bordered">
    <thead>
      <tr class="slds-line-height_reset">
        <template for:each={columns} for:item="column">
          <th key={column.id}>{column.name}</th>
        </template>
      </tr>
    </thead>
    <tbody>
      <template for:each={records} for:item="record">
        <tr key={record.id}>
          <template for:each={record.columns} for:item="column">
            <td key={column.id}>
              <lightning-input
                variant="label-hidden"
                class="fieldSize"
                type="number"
                step="0.01"
                label="visitValue"
                value={column.value}
                data-record-id={record.id}
                data-column-id={column.id}
                onchange={visitValueChange} 
                placeholder="00.00"
              ></lightning-input>
            </td>
          </template>
        </tr>
      </template>
    </tbody>
  </table>
</template>


推荐阅读