键入时Vue搜索Ajax响应数组

时间:2017-07-20 11:22:28

标签: javascript node.js ajax vue.js

我正在尝试在键入到Ajax调用的文本框时过滤列表。问题似乎是在Ajax准备好之前应用了过滤器。

HTML:

<input type="text" class="form-control" v-model="searchTerm">
<table>
    <tr v-for="food in filteredItems">
      <td>{{ food.name }}</td>
      <td>{{ food.energy }}</td>
    </tr>
</table>

助手/ index.js:

export default {
  getFoods() {
  return Vue.http.get('http://localhost:3000/foods/allfoods')
         .then((response) => {
             return response.data;
    });
  }
}

Vue组件:

import helpers from '../helpers'
export default {
  name: 'Search',
  mounted() {
    helpers.getFoods().then((response) => {
      this.foodData = response;
    });
  },
  data() {
    return {
      searchTerm: '',
      foodData: [],
    }
  },
  computed: {
    filteredItems() {
      return this.foodData.filter(function(food){return food.name.toLowerCase().indexOf(this.searchTerm.toLowerCase())>=0;});
    }
  }

当我加载页面或开始输入时,我得

  

'TypeError:undefined不是一个对象(评估'this.searchTerm')'。

如果我对foodData数组进行硬编码,那么一切都很完美。

我是否误解了某些事情和/或我做错了什么?

1 个答案:

答案 0 :(得分:0)

在计算过滤函数的回调中,map (const map& x);未指向Vue。

this

这是因为您使用computed: { filteredItems() { return this.foodData.filter(function(food){ // in this next line, this.searchTerm is likely undefined // because "this" is not the Vue return food.name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) >= 0; }); } } 作为回调,而function(food){...}将是包含范围。相反,请使用箭头函数,闭包或this

bind

&#13;
&#13;
computed: {
  filteredItems() {
    return this.foodData.filter(food => {
      // in this next line, this.searchTerm is likely undefined
      // because "this" is not the Vue
      return food.name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) >= 0;
    });
  }
}
&#13;
console.clear()

const foods = [{
    name: "orange",
    energy: 10
  },
  {
    name: "apple",
    energy: 8
  },
  {
    name: "banana",
    energy: 12
  },
  {
    energy: 1000
  }
]

const Search = {
    name: 'Search',
    template: `
      <div>
        <input type="text" class="form-control" v-model="searchTerm">
        <table>
          <tr v-for="food in filteredItems">
            <td>{{ food.name }}</td>
            <td>{{ food.energy }}</td>
           </tr>
         </table>   
      </div>
    `,
    mounted() {
      setTimeout(() => this.foodData = foods, 500)
    },
    data() {
      return {
        searchTerm: '',
        foodData: [],
      }
    },
    computed: {
      filteredItems() {
        const searchTerm = this.searchTerm.toLowerCase()
        return this.foodData
           .filter(food => food.name && food.name.toLowerCase().includes(searchTerm))
      }
    }
  }
new Vue({
  el:"#app",
  components: {Search}
})
&#13;
&#13;
&#13;

请参阅How to access the correct this inside a callback