Vue:带有条件的列名称的表过滤器

时间:2018-01-14 17:49:41

标签: javascript object search vue.js

我有以下代码来过滤表格。我从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()上显示为空。

我缺少什么?

2 个答案:

答案 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">&lt;</option>
      <option value="more_than">&gt;</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)

&#13;
&#13;
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;
&#13;
&#13;

我认为你的过滤逻辑错了。也许你可以试试这个。