Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将返回的JSON中的变量传递到基本搜索的单选列表筛选器时出现问题_Javascript_Vue.js_Axios_Vue Component - Fatal编程技术网

Javascript 将返回的JSON中的变量传递到基本搜索的单选列表筛选器时出现问题

Javascript 将返回的JSON中的变量传递到基本搜索的单选列表筛选器时出现问题,javascript,vue.js,axios,vue-component,Javascript,Vue.js,Axios,Vue Component,首先,我道歉。我是Vue的新手,有点挣扎。我有一个基本的搜索,其中我将向AWS CloudSearch传递一个关键字,然后返回JSON并显示结果。基本关键字搜索工作正常。我现在正试图将一个名为studenttype的数据对象传递给一个收音机列表,并基于该列表进行过滤。当我处理外部数据文件中的伪造数据时,一切都正常,但现在我获取的是真实数据,事实并非如此。我知道我必须从Axios获取数据,然后将其作为选项发布到TypeFilter.vue中。我只是不知道该怎么办。谢谢你的帮助 以下是我的App.v

首先,我道歉。我是Vue的新手,有点挣扎。我有一个基本的搜索,其中我将向AWS CloudSearch传递一个关键字,然后返回JSON并显示结果。基本关键字搜索工作正常。我现在正试图将一个名为
studenttype
的数据对象传递给一个收音机列表,并基于该列表进行过滤。当我处理外部数据文件中的伪造数据时,一切都正常,但现在我获取的是真实数据,事实并非如此。我知道我必须从Axios获取数据,然后将其作为选项发布到TypeFilter.vue中。我只是不知道该怎么办。谢谢你的帮助

以下是我的App.vue文件:

<template>
    <div class="app search">
        <!-- Search header -->
        <header id="searchHeader" class="search--header py-2 py-md-4">
            <div class="container">
                <div class="input-group">
                    <!-- Type filter -->
                    <TypeFilter v-model="studenttype" />

                    <!-- Location filter -->
                    <LocationFilter v-model="state" />

                    <!-- Search box -->
                    <SearchBox v-model="searchTerm"/>

                    <!-- More filters -->
                    <!--<div class="dropdown checkbox-dropdown mx-2">
                        <button class="btn btn-lg btn-white py-3 px-4 dropdown-toggle" type="button" id="dropdownMenuButtonFilters" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">More Filters</button>
                        <div class="dropdown-menu" aria-labelledby="dropdownMenuButtonFilters">
                        </div>
                    </div>-->

                    <!-- Search button -->
                    <button v-on:click="searchSubmit(searchTerm)" class="btn btn-lg btn-white ml-2 px-4 search-submit">Search</button>
                </div>

                <!-- Active filters (hidden for v0) -->
                <!--<div class="search--header--filters mt-3">
                    <span class="badge">Filter</span>
                    <span class="badge">Filter</span>
                    <span class="badge">Filter</span>
                </div>-->
            </div>
        </header>

        <!-- Main results -->
        <div class="container">
            <!-- Result count and show/sort -->
            <ResultCount v-model="page" :items="schools.length" :perPage="10"/>

            <!-- Results -->
            <SchoolList :schools="pageOfSchools"/>

            <!-- Pagination -->
            <Pagination v-model="page" :items="schools.length" :perPage="10"/>
        </div>
    </div>
</template>

<script>
    import SchoolList from './SchoolList'
    import ResultCount from './ResultCount'
    import Pagination from './Pagination'
    import SearchBox from './SearchBox'
    import TypeFilter from "./TypeFilter";
    import LocationFilter from "./LocationFilter";
    import getArraySection from '../utilities/get-array-section'
    export default {
        name: 'app',
        components: {SchoolList, ResultCount, Pagination, SearchBox, TypeFilter, LocationFilter},
        data: () => ({
            searchTerm: '',
            studenttype: '',
            state: '',
            schools: [],
            page: 1,
        }),
        computed: {
            pageOfSchools: function () {
                return getArraySection(this.schools, this.page, 10)
            }
        },
        watch: {
            studenttype: function () {
                this.filterSchools()
            },
            state: function () {
                this.filterSchools()
            }
        },

        methods: {
            searchSubmit: function(terms) {
                axios.post("/search/college", {
                    "search": {
                        terms: terms.split(' ')
                    }
                })
                    .then(response => {
                        this.schools = response.data.hit
                        console.log(response.data)
                    })
            },

            filterSchools: function () {
                const searchTerm = this.searchTerm.toLowerCase()
                const studenttype = this.studenttype

                if (searchTerm) {
                    result = result.filter(school => {
                        return (
                            school.title.toLowerCase().search(searchTerm) >= 0 ||
                            school.location.toLowerCase().search(searchTerm) >= 0
                        )
                    })
                }

                if (studenttype) {
                    result = result.filter(school => school.studenttype.indexOf(studenttype) >= 0)
                }

                this.schools = result
                this.page = 1
            }
        },
        created: function () {
            this.filterSchools()
        }
    }
</script>

好的,让我们一步一步来:

首先,我们必须通过
axios
获取初始学校列表:

searchSubmit: function(terms) {
  axios.post("/search/college", {
      "search": {
        terms: terms.split(' ')
      }
    })
    .then(response => {
      this.schools = response.data.hit
      console.log(response.data)
    })
}
然后我们应该获得所有可用的studenttypes,我会将其作为根组件中的计算函数:

computed: {
  allStudentTypes: function() {
    // checking if schools value is already available
    if (this.schools.hit) {
      let allStudentTypes = this.schools.hit.map(school => school.studenttype)
      // now we'll get unique values only
      let filteredStudentTypes = [...new Set(allStudentTypes)]
      return filteredStudentTypes
    } else {
      return []
    }
  }
}
然后我们将此值传递给
TypeFilter
组件:

computed: {
  allStudentTypes: function() {
    // checking if schools value is already available
    if (this.schools.hit) {
      let allStudentTypes = this.schools.hit.map(school => school.studenttype)
      // now we'll get unique values only
      let filteredStudentTypes = [...new Set(allStudentTypes)]
      return filteredStudentTypes
    } else {
      return []
    }
  }
}

TypeFilter
组件将完成其工作,并将
studenttype
变量传递给根组件

<TypeFilter :studenttype.sync="studenttype" ::options="studentTypes"/>
所以现在我们要过滤学校,我建议你们不要在数据中重写学校,让我们在计算部分这样做:

computed: {
  allStudentTypes: ...,
  filteredSchools: function() {
    const searchTerm = this.searchTerm.toLowerCase()
    const studenttype = this.studenttype
    let result = this.schools

    if (searchTerm) {
      result = result.filter(school => {
        return (
          school.title.toLowerCase().search(searchTerm) >= 0 ||
          school.location.toLowerCase().search(searchTerm) >= 0
        )
      })
    }

    if (studenttype) {
      result = result.filter(school => school.studenttype.indexOf(studenttype) >= 0)
    }

    return result
  }
}
所以现在我们可以随时传递
filteredSchools


我们还可以从
创建的
观看的
部分中删除
这个.filterschool()

因此,您希望
学生类型
成为
双向数据绑定。您可以通过Vue中的
:sync
实现这一点

<TypeFilter :studenttype.sync="studenttype" />
TypeFilter
不知道它需要过滤的所有
学生类型。所以你需要通过考试。一种方法是在父组件(App.vue)中使用computed属性:

现在,我们可以在
TypeFilter.vue
组件中提供
computed getter
作为
options
属性的绑定值

<TypeFilter :studenttype.sync="studenttype" ::options="studentTypes"/>
单击收音机时,
studenttype
的父项(App.vue)值将更新,以反映子项(TypeFilter.vue)中的选择。这种绑定将在两个组件之间工作,并且不需要进行任何处理

现在您有了
studenttype
,我们有了一个包含学校列表的数组,我们可以使用计算的getter来确定哪些学校应该可见(在App.vue中):

最后,将
visibleSchools
传递到
SchoolsList
组件,该组件将显示以下情况之一:

  • 只有符合
    学生类型
    的学校,如果
    学生类型
    是真实的,或者
  • 如果未设置
    studenttype
    set,则为所有学校

您能澄清一下您到底想做什么吗?我说得对吗?您想:通过
axios
获取
学校
-按
学校
类型过滤器
组件获取所有可用的
学生类型
值-根据此值制作一组单选按钮-通过父组件中选定的单选按钮过滤
学校
?尝试传递studenttype在App.vue的JSON中作为radio选项返回给TypeFiler.vue中名为“custom control custom radio”的div类。编辑:是的,你说得对。当JSON在一个外部数据文件中时,我让它工作,因为我刚刚将JSON导入TypeFilter.vue并引用了数据。然而,现在它不是硬编码的数据,我有点迷路了。谢谢!那么,我的最终TypeFilter.vue文件是什么样子的呢?除了那一部分,我什么都做得很好。你是自由职业者吗?我感谢你的深入帮助,但我认为我需要进一步的帮助。
computed: {
  studentTypes: {
    get: function() {
      return this.schools.map(function(school) {
        return school.studenttype
      })
    }
  }
}
<TypeFilter :studenttype.sync="studenttype" ::options="studentTypes"/>
this.$emit('udpate:studenttype', val)
visibleSchools: function() {
   switch(true) {
      case this.studenttype:
        return this.schools.filter(function(school) {
          return school.studenttype === this.studenttype
        })
        break
      default:
        return this.schools
   }
}