J'utilise Vue2.js
et Element UI
comme cadre. Je voudrais pouvoir filtrer une table qui est tranchée . Pour ce faire, j'utilise les composants table
et filter
dont la documentation est disponible ici .
La table n'est pas tranchée. Lorsque vous choisissez un filtre, une boucle parcourt chaque ligne et vérifie si la valeur de la colonne est égale au filtre.
La table est tranchée. Lorsque vous choisissez un filtre, une boucle parcourt chaque ligne résultant de la tranche et vérifie si la valeur de la colonne est égale à celle du filtre. En faisant cela, nous ne filtrons pas les valeurs "cachées".
J'ai fait un peu https://jsfiddle.net/acm3q6q8/3/ donc c'est plus facile à comprendre.
Tout cela a du sens puisque je ne travaille pas sur l’ensemble des données, mais sur une version découpée en tranches.
Une solution pourrait être de masquer les lignes au lieu de les exclure en découpant les données en tranches, mais je me demande s’il existe une meilleure solution?
jsfiddle
, n'affichez que 2 éléments. tag
pour n’afficher que les lignes dont la balise est Office
Aucune ligne n'est affichée car la ligne dont la variable tag
était office ne faisait pas partie de la table en tranches.
Lors du filtrage, je souhaite prendre en compte les lignes qui ne sont pas nécessairement affichées.
Cela devrait fonctionner correctement avec un filtre multiple (c.-à-d. Que je sélectionne plusieurs balises)
Dans la même mesure, si vous souhaitez trier le nom par ordre alphabétique, Albert ne sera pas affiché si vous n’affichez que 2 éléments.
Vous pouvez gérer l'événement filter-change
sur le composant table (documenté ici ) et filtrer/découper vous-même.
var Main = {
data() {
return {
numberItemToShow : 4,
tableData: [...],
filter: []
}
},
computed : {
filterData() {
if (!this.filter.length)
return this.tableData.slice(0, this.numberItemToShow)
else
return this.tableData
.filter(row => this.filter.includes(row.tag))
.slice(0, this.numberItemToShow);
}
},
methods: {
onFilterChange(filters){
if (filters.tag)
this.filter = filters.tag;
}
}
}
Et le modèle
<template>
<input v-model="numberItemToShow" placeholder="edit me">
<p>Number of item to display: {{ numberItemToShow }}</p>
<el-table ref="tab" :data="filterData" border style="width: 100%" @filter-change="onFilterChange">
<el-table-column prop="name" label="Name" sortable>
</el-table-column>
<el-table-column prop="tag" label="Tag" column-key="tag" :filters="[{ text: 'Home', value: 'Home' }, { text: 'Office', value: 'Office' }]">
<template scope="scope">
<el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'" close-transition>{{scope.row.tag}}</el-tag>
</template>
</el-table-column>
</el-table>
</template>
Exemple .
Le problème est que le découpage est effectué avant le filtrage. Le filtre doit voir les données d'origine et le comptage de lignes doit faire partie du filtrage.
Étant donné que le filtre examine une ligne à la fois, il est un peu délicat de garder une trace des lignes correspondantes. Ce que j’ai fait ici, c’est de garder un compteur de lignes correspondantes qui est remis à zéro lorsque la ligne examinée est la première ligne de données. C'est hacky, mais ça marche. Il y a peut-être un meilleur moyen; Je ne suis pas familier avec le widget de table.
var Main = {
data() {
return {
numberItemToShow : 4,
tableData: [{
name: 'One',
tag: 'Home'
}, {
name: 'Two',
tag: 'Home'
}, {
name: 'Three',
tag: 'Home'
}, {
name: 'Four',
tag: 'Office'
}],
scratchCounter: 0
}
},
methods: {
filterTag(value, row) {
const matched = row.tag === value;
if (row === this.tableData[0]) {
this.scratchCounter = 0;
}
if (matched) {
++this.scratchCounter;
}
return this.scratchCounter <= this.numberItemToShow && matched;
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
@import url("//unpkg.com/element-ui/lib/theme-default/index.css");
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui/lib/index.js"></script>
<div id="app">
<template>
<input v-model="numberItemToShow" placeholder="edit me">
<p>Number of item to display: {{ numberItemToShow }}</p>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="name" label="Name">
</el-table-column>
<el-table-column prop="tag" label="Tag" :filters="[{ text: 'Home', value: 'Home' }, { text: 'Office', value: 'Office' }]" :filter-method="filterTag">
<template scope="scope">
<el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'" close-transition>{{scope.row.tag}}</el-tag>
</template>
</el-table-column>
</el-table>
</template>
</div>