将ag grid与vuejs结合使用,如何在不重置每个单元格的情况下使每个单元格具有反应性?

问题描述 投票:0回答:1

我在 Vue3 中的 AgGrid 中遇到了一些关于反应性的问题。

我希望使用自定义输入组件(CellRenderer + CellRendererParams)使每个单元格对其他单元格的更改做出反应。

例如,我想连接一个人的名字和姓氏。我知道有 valueFormatter 属性,但我不想使用它,因为每个单元格都可以是输入,甚至是串联。最重要的是,我希望我通过 props 传递的“rowData”对象是反应性的,所以当我更改表中的数据时,它应该在外部更新,反之亦然

我做了一个 Plunk 来向你展示我的方法:https://plnkr.co/edit/h4eIDnV9pLjqFY0L?open=main.js 这是我认为的主要部分。这是我更改行数据的地方。当我更改它时,我希望其他单元格“更新”而不是刷新。 `函数 onUpdate(值) { // -- 设置数据值 -- // 使用此方法,我的主要数据对象会更新,但其他数据对象不会更新,并且我会失去对输入的关注 props.params.node.setDataValue(props.params.field, value.target.value);

  // -- SET DATA -- 
  // With this method, I should list all columns to make an update and decide which one I would like to update, and I loose focus on my input, not viable
  props.params.data.fullname = [props.params.data.firstname, props.params.data.lastname].join(" "),
  props.params.data[props.params.field] = value.target.value;
  props.params.node.setData(props.params.data);

  // The ideal solution :
  props.params.data[props.params.field] = value.target.value; // And nothing else
}`

当我使用 setData()、setDataValue() 或 setRowData() 时,它会重新渲染整个行或表,因此当我直接改变 props.params.data 或 props.params.node 中的字段时,我会失去对输入的关注.数据什么也没发生。

事实上,我使用 v-model 声明了 rowData 但没有任何反应,这让我觉得我在使用数据的方式中遗漏了一些东西,但我不知道是什么。

我提前感谢您帮助我🙂

我尝试使用 setDataValue、setData 和 setRowData。每次单元格都会重置,我就会失去对组件的关注。

我期待的不是组件的刷新,而是道具的改变。

vuejs3 ag-grid ag-grid-vue
1个回答
0
投票

为了使组件可更新,它必须公开一个

refresh()
方法。如果没有,更新将用新实例替换整个组件,从而破坏您的输入元素,从而导致焦点丢失。

据我所知,ag-grid-vue 不能很好地使用设置功能,我建议使用 options API。所以你的组件看起来像这样:

export default {
  template: `<input :value="cellValue" @input="onInput"/>`,
  props: ['params'],
  expose: ['refresh'], // <---- expose refresh method
  data(){
    return {
      cellValue: null, // <---- local copy of cell value
    }
  },
  methods: {
    onInput(event) {
      const fieldId = this.params.field
      const value = event.target.value
      this.params.node.setDataValue(fieldId, value); // <---- trigger cell update
    },
    refresh(newParams){
      this.cellValue = newParams.value  // <---- update local value
    }
  },
  created(){
    this.refresh(this.params) // <---- initial setup of local value
  },
}

现在组件在初始化时设置本地值,并通过公开的

refresh()
方法更新该值。

目前,手动管理单元格值似乎是唯一的选择。理论上,ag-grid-vue 组件支持

autoParamsRefresh
属性,它设置默认的
refresh()
方法,该方法在更新时更新所有组件属性(在 releasenotes 中搜索描述)。然而,它似乎不适用于 Vue 3,因为它只是尝试覆盖只读的 props,从而给你一个
Uncaught TypeError: proxy set handler returned false for property '"params"'
错误。


如果您尝试上述方法,您会发现它有效,但仅在第一次编辑后有效。第一次编辑值时,组件仍会被替换并且焦点会丢失。这很烦人。简而言之,当您使用

v-model
绑定行时,您必须使用
shallowRef
,这样更改检测就不会混淆:

<template>
  <ag-grid-vue
    v-model="rows"
    ...
  />
</template>
<script>

</script setup>
  const rows = shallowRef([...])
</script> 

现在

rows
中的项目将不再是代理对象,与ag-grid-vue中设置的值相同,避免了最初的错误。


最后,您可以将名字和姓氏组合为全名。我会为此使用 getter 和 setter:

{ 
  firstname: "John", 
  lastname: "Doe", 
  get fullname(){
    return this.firstname + ' ' + this.lastname
  },
  set fullname(name){
    const [fn, ln] = name.split(' ')
    this.firstname = fn
    this.lastname = ln
  }
}

但还有其他选择。如果你想通过 ag-grid-vue 来做到这一点,你必须使用

setDataValue()
而不是
setData()
,因为后者总是会重新初始化该行的所有组件。


这是在游乐场

这对你有用吗?

© www.soinside.com 2019 - 2024. All rights reserved.