Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 [Bug]: dialog-select 数据反查回显功能不太能用 #2570

Closed
sunny-Fung opened this issue Nov 28, 2024 · 3 comments
Closed

🐛 [Bug]: dialog-select 数据反查回显功能不太能用 #2570

sunny-Fung opened this issue Nov 28, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@sunny-Fung
Copy link

sunny-Fung commented Nov 28, 2024

Version

3.19.0

Vue Version

3.4.27

Link to minimal reproduction

https://opentiny.design/vue-playground?cmpId=dialog-select&fileName=nest-grid-multi.vue&apiMode=Composition&mode=pc&theme=default

Step to reproduce

  1. 打开演练场,链接
  2. 输入以下代码
  3. 点击“打开窗口”按钮=》检查已选列表与左边表格的数据回显效果=》关闭窗口
  4. 点击“设置初始值”按钮,重复步骤3。可以看出来,初始值只能写死在配置里,不能动态设置(比如我用props传入一个初始值作为配置,是不会生效的)
<template>
  <div class="tiny-demo">
    <tiny-button @click="setValue">设置初始值</tiny-button>
    <tiny-button @click="state.visible = !state.visible">{{ `${state.visible ? '关闭' : '打开'}窗口` }}</tiny-button>
    <p>
      
    </p>
    <tiny-dialog-select
     
      ref="dialogSelect"
      class="tiny-demo-dialog-select"
      :visible="state.visible"
      @update:visible="state.visible = $event"
      popseletor="grid"
      :multi="state.multi"
      :dialog-op="state.dialogOp"
      :grid-op="state.gridOp"
      :pager-op="state.pagerOp"
      :selected-box-op="state.selectedBoxOp"
      :remote-search="remoteSearch"
      :lookup-method="lookupMethod"
      :before-close="beforeClose"
      @size-change="onSizeChange"
      @current-change="onCurrentChange"
      @change="onDialogSelectChange"
      value-field="id"
      text-field="name"
      :main-height="240"
    >
      <template #search>
        <div class="tiny-demo-search">
          <div class="tiny-demo-search-left">
            <tiny-search placeholder="公司名称" is-enter-search @search="onSearch"></tiny-search>
          </div>
          <div class="tiny-demo-search-right">
            <tiny-select
              v-model="state.searchData.city"
              placeholder="选择城市"
              :options="state.options"
              clearable
              @change="onCitySearch"
            ></tiny-select>
          </div>
        </div>
      </template>
    </tiny-dialog-select>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import { TinyDialogSelect, TinyButton, TinySearch, TinySelect } from '@opentiny/vue'
import Sortable from 'sortablejs'

// 模拟服务侧数据
const datas = [
  { id: '1', name: 'GFD科技有限公司', city: '福州', province: '福建' },
  { id: '2', name: 'WWW科技有限公司', city: '深圳', province: '广东' },
  { id: '3', name: 'RFV有限责任公司', city: '中山', province: '广东' },
  { id: '4', name: 'TGB科技有限公司', city: '龙岩', province: '福建' },
  { id: '5', name: 'YHN科技有限公司', city: '韶关', province: '广东' },
  { id: '6', name: 'WSX科技有限公司', city: '黄冈', province: '湖北' },
  { id: '7', name: 'KBG物业有限公司', city: '赤壁', province: '湖北' },
  { id: '8', name: '深圳市福德宝网络技术有限公司', city: '深圳', province: '广东' },
  { id: '9', name: 'KBG物业有限公司', city: '赤壁', province: '湖北' },
  { id: '10', name: '深圳市福德宝网络技术有限公司', city: '深圳', province: '广东' }
]

// 接口1:根据一组数据id查询这组数据
const queryRowsByIds = (ids) => {
  console.log(1234)
  return datas.filter((row) => ~ids.indexOf(row.id))
}

// 接口2:分页过滤查询
const queryFilter = (pager, search) => {
  const { currentPage, pageSize } = pager
  const { name, city } = search
  const start = (currentPage - 1) * pageSize
  const end = currentPage * pageSize
  // 过滤:名称模糊匹配,城市精确匹配
  const filtered = datas.filter((row) => (!name || ~row.name.indexOf(name)) && (!city || row.city === city))
  // 分页
  const data = filtered.slice(start, end)

  return { data, total: datas.length }
}

const beforeClose = () => {
  return true
}

const state = reactive({
  multi: true,
  searchData: { name: '', city: '' },
  options: [
    { value: '福州', label: '福州' },
    { value: '深圳', label: '深圳' },
    { value: '赤壁', label: '赤壁' }
  ],
  visible: false,
  dialogOp: {
    top: '20vh',
    width: '800px',
    title: '选择公司',
    beforeClose,
    dialogClass: 'custom-dialog-class'
  },
  gridOp: {
    columns: [
      { field: 'id', title: 'ID', width: 50 },
      { field: 'name', title: '名称', showOverflow: 'tooltip' },
      { field: 'province', title: '省份', width: 80 },
      { field: 'city', title: '城市', width: 80 }
    ],
    data: [], // 多选时生效
    selectConfig: {
      reserve: true,
      checkRowKeys: ['1'] 
    },
    border: false, // 设置边框
    size: 'small', // 设置表格尺寸
    // 单选时生效
    radioConfig: { checkRowKey: '3' }
  },
  pagerOp: {
    currentPage: 1,
    pageSize: 5,
    pageSizes: [5, 10],
    total: 0,
    layout: 'prev, pager, next'
  },
  selectedBoxOp: {
    config: {
      pkField: 'id',
      pkFieldType: 'string',
      showField: ['name', 'city'],
      plugin: Sortable
    }
  }
})

const dialogSelect = ref('')

const onSizeChange = (pageSize) => {
  state.pagerOp.pageSize = pageSize

  dialogSelect.value.valuequeryGridData()
}

const onCurrentChange = (currentPage) => {
  state.pagerOp.currentPage = currentPage

  dialogSelect.value.queryGridData()
}

const onSearch = (key, value) => {
  state.searchData.name = value
  state.pagerOp.currentPage = 1
  dialogSelect.value.queryGridData()
}

const onCitySearch = (value) => {
  state.searchData.city = value
  state.pagerOp.currentPage = 1
  dialogSelect.value.queryGridData()
}

const remoteSearch = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      const res = queryFilter(state.pagerOp, state.searchData)
      // 序列化是为了模拟每次返回的都是新对象
      const copy = JSON.parse(JSON.stringify(res.data))

      state.gridOp.data = copy
      state.pagerOp.total = res.total
      // promise返回执行下一步
      resolve()
    }, 300)
  })
}

const lookupMethod = (values) => {
	console.log('lookupMethod', values)
  return new Promise((resolve) => {
    setTimeout(() => {
      const res = queryRowsByIds(values)
      // 序列化是为了模拟每次返回的都是新对象
      const copy = JSON.parse(JSON.stringify(res))
      resolve(copy)
    }, 300)
  })
}

const onDialogSelectChange = (values, texts, selectedDatas) => {
  // 打印change回调数据,控制台查看
  console.log({ values, texts, selectedDatas })
}

const setValue = () => {
  state.gridOp.selectConfig.checkRowKeys = ['1', '6']
}
</script>

<style scoped lang="less">
.tiny-demo-search {
  display: flex;

  .tiny-demo-search-left {
    flex: 1;
  }

  .tiny-demo-search-right {
    width: 216px;
    margin-left: 8px;
  }
}
</style>

What is expected

我需要对dialog-select做二次封装(固定部分配置),初始值会通过props传入(初始值场景使用普遍,例如编辑功能,需要带出已选的内容数据回显),是很重要的一个需求!!

What is actually happening

目前初始值效果鸡肋,没有人会直接把值写死。

What is your project name

111

Any additional comments (optional)

No response

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Title: 🐛 [Bug]: dialog-select data reverse check and echo function does not work well

@MomoPoppy
Copy link
Collaborator

此问题不属于bug,目前不支持动态设置值。
image
表格组件不是这样去动态设置选中行的。
此处可以考虑新增 v-model 或者保留 grid 实例供用户动态设置选中行。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


This problem is not a bug, and dynamic setting of values ​​is currently not supported.
image
This is not how the table component dynamically sets the selected rows.
You can consider adding a new v-model here or retaining a grid instance for users to dynamically set selected rows.

@kagol kagol added the bug Something isn't working label Dec 5, 2024
@zzcr zzcr closed this as completed Dec 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants