我有以下代码来过滤表格。我从age
下拉列表中选择了一列,然后从<
等其他下拉列表中选择运算符,并搜索20
之类的输入,并希望在其上搜索表格。
过滤:
// Select column name
<select class="dv-header-select" v-model="query.search_column">
<option v-for="column in columns" :value="column">{{column}}</option>
</select>
// Select condition(<,>,<=,>=)
<select class="dv-header-select" v-model="query.search_operator">
<option v-for="(value, key) in operators" :value="key">{{value}}</option>
</select>
// Search value
<input type="text" class="dv-header-input" placeholder="Search"
v-model="query.search_input">
请阅读JS部分中的代码注释以获得想法。
<tr v-for="row in getSearchedRow">
<td v-for="(value, key) in row">{{value}}</td>
</tr>
JS:
data() {
return {
model: { data: [] },
// populating on API call
columns: {},
query: {
search_column: 'id',
search_operator: 'equal',
search_input: ''
}
},
getSearchedRow: function() {
return this.model.data.filter(row => {
let value = row[this.query.search_column];
for(var key in row){
if(String(row[key]).indexOf(this.query.search_input) !== -1){
// Return true required to populate table
if(this.query.search_column.length < 1) {
return true;
}
// when condition gets here, The table shows 0 records
if(this.query.search_operator == 'less_than') {
return value < this.query.search_input;
}
}
}
});
}
该表因第一个if()
而填充,但在第二个if()
上显示为空。
我缺少什么?
答案 0 :(得分:1)
您无需迭代对象的每个键并测试它们是否与所需值部分匹配。您可以将过滤器简化为此类
getSearchedRow: function() {
if (this.query.search_column === '')
return this.model.data;
return this.model.data.filter(row => {
const value = row[this.query.search_column];
// adapt to what your actual operators do
switch (this.query.search_operator) {
case 'less_than': return value < this.query.search_input;
case 'more_than': return value > this.query.search_input;
// and so on
default: return false;
}
});
}
请注意,如果您想获得准确的结果,您可能必须使用一种机制将值转换为数字。例如:
data() {
return {
model: { data: [
{id: 1, x: "a", age: 18},
{id: 2, x: "a", age: 19},
{id: 3, x: "b", age: 22},
{id: 4, x: "b", age: 20},
] },
columns: {
id: {
cast: function(v) {
return +v;
}
},
age: {
cast: function(v) {
return +v;
}
}
},
query: {
search_column: 'age',
search_operator: 'equal',
search_input: ""
}
};
},
computed: {
getSearchedRow: function() {
if (this.query.search_column === '')
return this.model.data;
const col = this.query.search_column;
const requiredval = (this.columns[col] && this.columns[col].cast) ? this.columns[col].cast(this.query.search_input) : this.query.search_input;
return this.model.data.filter(row => {
const value = row[col];
switch (this.query.search_operator) {
case 'less_than': return value < requiredval;
case 'more_than': return value > requiredval;
case 'equal': return value === requiredval;
default: return false;
}
});
}
}
和演示
new Vue({
el: '#app',
data() {
return {
model: { data: [
{id: 1, x: "a", age: 18},
{id: 2, x: "a", age: 19},
{id: 3, x: "b", age: 22},
{id: 4, x: "b", age: 20},
] },
columns: {
id: {
cast: function(v) {
return +v;
}
},
age: {
cast: function(v) {
return +v;
}
}
},
query: {
search_column: 'age',
search_operator: 'equal',
search_input: ""
}
};
},
computed: {
getSearchedRow: function() {
if (this.query.search_column === '')
return this.model.data;
const col = this.query.search_column;
const requiredval = (this.columns[col] && this.columns[col].cast) ? this.columns[col].cast(this.query.search_input) : this.query.search_input;
return this.model.data.filter(row => {
const value = row[col];
switch (this.query.search_operator) {
case 'less_than': return value < requiredval;
case 'more_than': return value > requiredval;
case 'equal': return value === requiredval;
default: return false;
}
});
}
}
});
<script src="https://unpkg.com/vue"></script>
<div id="app">
<select class="dv-header-select" v-model="query.search_column">
<option value="">Everything</option>
<option value="id">ID</option>
<option value="age">Age</option>
<option value="x">X</option>
</select>
<select class="dv-header-select" v-model="query.search_operator">
<option value="equal">=</option>
<option value="less_than"><</option>
<option value="more_than">></option>
</select>
<input type="text" class="dv-header-input" placeholder="Search"
v-model="query.search_input">
<table>
<tr v-for="row in getSearchedRow">
<td v-for="(value, key) in row">{{value}}</td>
</tr>
</table>
</div>
答案 1 :(得分:0)
function filter(rows, query) {
return rows.filter(r => {
if (query.input.length < 1) {
return true
}
if (query.col.length < 1) {
return true
}
const v = r[query.col]
const i = query.input
switch (query.op) {
case '=':
return v == i
case '<':
return v < i
case '>':
return v > i
case '<=':
return v <= i
case '>=':
return v >= i
default:
throw "unreachable"
}
})
}
const rows = [{
id: 1,
age: 20
}, {
id: 2,
age: 30
}]
console.log(filter(rows, {
col: 'id',
op: '=',
input: '2'
}))
console.log(filter(rows, {
col: 'age',
op: '<',
input: '25'
}))
console.log(filter(rows, {
col: '',
op: '<',
input: '25'
}))
console.log(filter(rows, {
col: 'id',
op: '<',
input: ''
}))
&#13;
我认为你的过滤逻辑错了。也许你可以试试这个。