繁体   English   中英

bootstrap-vue b-table:在表重新加载时保持扩展行扩展

[英]bootstrap-vue b-table: keep expanded rows expanded on table reload

这个的展开/折叠部分工作得很好。

现在我正在使用 javascript startInterval() 每 2 秒重新加载一次表。 最终这将转移到 web sockets。

通常,作为表加载/重新加载的一部分,系统通过检查 row.detailsShowing 来检查它是否应该在详细信息列中显示图标“^”或“v”,这工作正常。

getChevron(row, index) {
 if (row.detailsShowing == true) {     
   return "chevronDown";
 }
   return "chevronUp";
}

当用户在关系列中选择“^”图标时,会调用@click=row.toggleDetails来展开行,然后调用 function v-on:click="toggleRow(row)"来跟踪哪一行用户选择。 这使用服务器端系统生成的 guid 进行跟踪。

在 2 秒内,表格将重新加载并且行折叠。 在加载/重新加载时,在它加载的第一列中,关系,我调用 function checkChild(row),对照我本地存储的数组检查行 guid,以确定这是否是应该在加载时扩展的行。

<template #cell(relationship)="row"> {{checkChild(row)}} <\template>

如果行 guid 与数组中的一个匹配,我尝试设置

checkChild(row){
  var idx = this.showRows.indexOf( row.item.id);
    if(idx > -1){
     row.item.detailsShowing = true;
     row.rowSelected = true;
     row.detailsShowing == true
     row._showDetails = true;
   }
}

并且我可以看到我找到了匹配项,但是这些变量都没有设置为 true 使展开的行保持打开状态,该行总是在重新加载时折叠

有人对我如何使行在重新加载表时保持打开状态有任何想法吗?

您的代码存在问题是因为 Vue 2 警告。 在对象被添加到data后向对象添加属性不会是反应性的。 要解决这个问题,您必须使用Vue.set

您可以在此处阅读更多相关信息。

但是,像在模板中那样调用 function 似乎是不好的做法。 相反,您应该在获取数据后执行此操作,或者使用计算属性之类的东西来执行映射。

这里有两个简化的例子。

API 调用后的映射

{
  data() {
    return {
      items: [],
      showRows: []
    }
  },
  methods: {
    async fetchData() {
      const { data } = await axios.get('https://example.api')
      foreach(item of data) {
        const isRowExpanded = this.showRows.includes(item.id);
        item._showDetails = isRowExpanded;
      }
      this.items = data;
    }
  }
}

使用计算

{
  computed: {
    // Use `computedItems` in `<b-table :items="computedItems">`
    computedItems() {
      const { items, showRows } = this;
      return items.map(item => ({
        ...item, 
        _showDetails: .showRows.includes(item.id)
      }))
    }
  },
  data() {
    return {
      items: [],
      showRows: []
    }
  },
  methods: {
    async fetchData() {
      const { data } = await axios.get('https://example.api')
      this.items = data;
    }
  }
}

有关更完整的示例,请查看下面的代码段。

 const { name, datatype, image } = faker; const getUser = () => ({ uuid: datatype.uuid(), personal_info: { first_name: name.firstName(), last_name: name.lastName(), gender: name.gender(), age: Math.ceil(Math.random() * 75) + 15 }, avatar: image.avatar() }); const users = new Array(10).fill().map(getUser); new Vue({ el: "#app", computed: { computed_users() { const { expanded_rows, users } = this; return users.map((user) => ({...user, _showDetails: expanded_rows[user.uuid] })); }, total_rows() { const { computed_users } = this; return computed_users.length; } }, created() { this.users = users; setInterval(() => { users.push(getUser()); this.users = [...users]; }, 5000); }, data() { return { per_page: 5, current_page: 1, users: [], fields: [{ key: "avatar", class: "text-center" }, { key: "name", thClass: "text-center" }, { key: "personal_info.gender", label: "Gender", thClass: "text-center" }, { key: "personal_info.age", label: "Age", class: "text-center" } ], expanded_rows: {} }; }, methods: { onRowClicked(item) { const { expanded_rows } = this; const { uuid } = item; this.$set(expanded_rows, uuid, ;expanded_rows[uuid]); } } });
 <link href="https://unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.css" rel="stylesheet" /> <script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script> <script src="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.js"></script> <script src="https://unpkg.com/faker@5.5.3/dist/faker.min.js"></script> <div id="app" class="p-3"> <b-pagination v-model="current_page":per-page="per_page":total-rows="total_rows"> </b-pagination> <h4>Table is refresh with a new item every 5 seconds.</h4> <h6>Click on a row to expand the row</h6> <b-table:items="computed_users":fields="fields" bordered hover striped:current-page="current_page":per-page="per_page" @row-clicked="onRowClicked"> <template #cell(avatar)="{ value }"> <b-avatar:src="value"></b-avatar> </template> <template #cell(name)="{ item: { personal_info: { first_name, last_name } }}"> {{ first_name }} {{ last_name }} </template> <template #row-details="{ item }"> <pre>{{ item }}</pre> </template> </b-table> </div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM