javascript - Vue 在输入时搜索 Ajax 响应数组

标签 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>

helpers/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 is not an object (evaluating 'this.searchTerm')'.

如果我对 foodData 数组进行硬编码,一切都会完美无缺。

我是否误解了什么和/或我做错了什么?

最佳答案

在计算的过滤器函数的回调中,this 没有指向 Vue。

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

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;
    });
  }
}

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}
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  <search></search>
</div>

参见 How to access the correct this inside a callback .

关于javascript - Vue 在输入时搜索 Ajax 响应数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45213269/

相关文章:

angularjs - Spring Security CSRF token 存储库 Cookie 会自动处理所有 Ajax 请求吗?

javascript - 使用ajax将数组数据从浏览器中的javascript传递到spring mvc Controller

javascript - 将 Laravel 路由参数传递给 JavaScript

将 AWS cdn 放入 JS 文件时未定义 JavaScript AWS

javascript - 滑动以更改页面 - 不同的域

node.js - 删除磁盘后使用 npm 安装 firebase 时出错

node.js - 如何在 Node.js 中验证来自 QLDB 的文档?

javascript - Jquery 输入掩码时间不工作

javascript - Fabric.js 行可选属性未保存在 Canvas 的 JSON 中

asp.net-mvc - Node.Js 和 ASP.NET MVC 应用程序之间的通信