0

我在一个苗条的项目中使用virtuallist 组件。我已将过滤添加到列表中。我的问题是,当我过滤列表时,我的项目中的一个函数停止工作,我假设是因为过滤时列表项尚未在 dom 中?

该项目使用两个输入将医疗单位从公制单位转换为国际单位。更改一个输入会自动转换另一个。在过滤之前,转换一切正常,但在输入项目名称(例如 Type Zinc)后,过滤项目中的输入转换失败。不发生转换。我已经将 afterUpdate 作为一个选项进行了研究,但不确定如何实现它。

---------添加信息---------

问题在于尚未查看的列表项。尝试输入“zinc”,然后更改 Zinc(失败)的输入值与输入 Acetone(项目已在视图中)并更改这些输入(它有效)。

这是一个有效的REPL

剧本:

 <script>
 import VirtualList from './VirtualList.svelte';
 import unitsH from './data.js';


let searchTerm = "";
let start;
 let end;
  $: filteredList = unitsH.filter(item => item.name.toLowerCase().indexOf(searchTerm) !== -1);

function setBothFromSIH(value, i) {
const {factor, siValue} = unitsH[i];
unitsH[i].siValue = +value;
unitsH[i].usValue = +(value / factor).toFixed(2);
}
function setBothFromUSH(value, i) {
const {factor, usValue} = unitsH[i];
unitsH[i].usValue = +value;
unitsH[i].siValue = +(value * factor).toFixed(2);
 }
  </script>

使用简化的 html 代码:

 <VirtualList items={filteredList} bind:start bind:end let:item >

<div class="border" style="overflow-x: scroll;"> <div><div>

          <div class="name">{item.name}</div>
         <span>Specimen: {item.specimen} </span>
     <span> Conversion Factor: {item.factor} </span>
        </div>
 <div>
  <label>US Range:{item.conventionalRange} {item.conventionalUnit}</label>
           <input  name="us{filteredList.indexOf(item)}" value={item.usValue} on:input="{e => setBothFromUSH(e.target.value, filteredList.indexOf(item))}"  type=number placeholder=" US">

         </div> 
 <div>
 <label>SI Range: {item.siRange} {item.siUnit}</label>
           <input name="si{filteredList.indexOf(item)}" value={item.siValue} on:input="{e => setBothFromSIH(e.target.value, filteredList.indexOf(item))}" type=number placeholder="SI">

         </div></div> </div>
 </VirtualList>

 <p>showing items {start}-{end}</p>

感谢您为使其正常工作提供的任何帮助!

4

2 回答 2

0

这是您的过滤器的一个小问题。您将产品名称转换为小写而不是过滤器术语;)如果您输入acetone而不是Acetone,那么它可以工作。修复:

$: filteredList = unitsH.filter(item => item.name.toLowerCase().indexOf(searchTerm.toLowerCase()) !== -1);

编辑:

不为某些过滤元素调用函数的问题是您显示但仍然在列表filteredList上进行查找。unitsH把它改成这个就可以了:

    function setBothFromSIH(value, i) {
        const {factor, siValue} = filteredList[i];
        filteredList[i].siValue = +value;
        filteredList[i].usValue = +(value / factor).toFixed(2);
    }

    function setBothFromUSH(value, i) {
        const {factor, usValue} = filteredList[i];
        filteredList[i].usValue = +value;
        filteredList[i].siValue = +(value * factor).toFixed(2);
    }

快乐黑客!

于 2020-06-08T05:50:21.237 回答
0

您的问题是由使用错误的索引引起的,在更改处理程序中您传递了项目的索引,filteredIndex但随后您使用该索引更改了数组中该索引上的项目unitsH

您可以通过以下方式查看: - 重新开始 - 记下对乙酰氨基酚的值(索引 0) - 搜索锌 - 更改锌的值(过滤列表中的索引 0) - 清除搜索

->> 对乙酰氨基酚发生了变化,因为这是以单位 H 为单位的索引 0

您可以通过传入原始数组的索引来轻松解决此问题:

<input name="si{filteredList.indexOf(item)}" value={item.siValue} on:input="{e => setBothFromSIH(e.target.value, unitsH.indexOf(item))}" type=number placeholder="SI">

但是,如果您将每个项目的标记移动到单独的组件中,您可以通过直接与属性交互而不是尝试在数组中更改它们来大大简化此操作。

于 2020-06-08T08:38:01.673 回答