Bootstrap-vue: Как отфильтровать второй набор данных, используя встроенный компонент фильтрации таблиц? - PullRequest
0 голосов
/ 19 мая 2019

Я использую VueJS и компонент таблицы Bootstrap-vue и его параметр фильтрации для фильтрации данных таблицы. Однако похоже, что компонент фильтрации Bootstrap / Table можно применять только к данным массива исходных элементов, и, следовательно, «в настоящее время невозможно фильтровать данные на основе пользовательского рендеринга виртуальных столбцов» в соответствии с документацией: https://bootstrap -vue.js.org / документы / компоненты / таблица # фильтрация

Моя ситуация такова, что у меня есть исходный массив данных, который содержит только идентификаторы пользователей, но у меня есть другой массив данных, который содержит идентификаторы и фактические имена пользователей. таким образом, в моей таблице вместо того, чтобы показывать идентификаторы пользователей, я хочу показать реальные имена. Я создал специальную функцию обратного вызова «formatter» ( docs ) и могу отображать имена в таблице, но компонент фильтра не будет выполнять поиск по этой причине, поскольку он не является частью исходного массива данных.

Есть ли другой способ, которым я могу подойти к этому, чтобы у меня также был поиск фильтра по столбцу «Назначено»?

Мой демонстрационный код здесь Нажмите на ссылку "POSTS" в этом редакторе

<template>
  <div>
    <b-table :items="posts" :fields="fields">
      <!-- A custom formatted column -->
      <template slot="name" slot-scope="data">{{ data.value.userId }}</template>
    </b-table>
  </div>
</template>

<script>
import axios from "axios";
import users from "../assets/users.json";
export default {
  data() {
    return {
      posts: [],
      users: [],
      // key name is the slot name
      fields: [
        { key: "id" },
        { key: "title" },
        { key: "body" },
        { key: "userId", label: "Assigned To", formatter: "assignNames" }
      ]
    };
  },
  created() {
    this.getPosts();
    this.getNames();
  },
  methods: {
    getPosts() {
      axios.get("https://jsonplaceholder.typicode.com/posts").then(resp => {
        this.posts = resp.data;
      });
    },
    getNames() {
      setTimeout(
        () =>
          Promise.resolve(users).then(resp => {
            this.users = resp.data;
          }),
        1234
      );
    },
    assignNames(id) {
      const user = this.users.find(user => user.id === id);
      return user ? `${user.first_name} ${user.last_name}` : "loading...";
    }
  }
};
</script>

1 Ответ

0 голосов
/ 19 мая 2019

Вам нужно создать массив поверх постов и пользователей. Всегда хорошо готовить данные, так как они нужны для отображения.

Вычисленные свойства хороши для этого.

Кроме того, поскольку пользователи приходят из Sync JSON, вам не нужно обещание или setTimeout.

<script>
    import axios from "axios";
    import users from "../assets/users.json";
    export default {
        data() {
            return {
                rawPosts: [],
                // key name is the slot name
                fields: [
                    { key: "id" },
                    { key: "title" },
                    { key: "body" },
                    { key: "user", label: "Assigned To" }
                ]
            };
        },
        created() {
            this.loadPosts();
        },
        methods: {
            loadPosts() {
                axios.get("https://jsonplaceholder.typicode.com/posts").then(resp => {
                    this.rawPosts = resp.data;
                });
            },
            userFrom(id) {
                const user = users.data.find(user => user.id === id);
                return user && `${user.first_name} ${user.last_name}`;
            }
        },
        computed:{
            posts(){
                if(this.rawPosts.length && users.length){
                    return this.rawPosts.map(rawPost => ({...rawPost, user: this.userFrom(rawPost.userId)}));
                }else{
                    //loading case
                }
            }
        }
    };
</script>
...