У меня есть массив поля выбора Depend, который содержит университеты и курсы. В каждом университете есть свой курс. и я построил раскрывающийся список курсов, который зависит от университета. Я могу успешно получить университетский курс по запросу сервера, но проблема в том, что когда я меняю выбранный университет, он меняет все поля курса. Как я могу решить эту проблему, дайте мне несколько идей. Спасибо
<template>
<form @submit.prevent = "handleSubmit">
<div class = "col col-md-12">
<div v-for = "(interest, index) in interests" :key = "index" class = "row">
<div class = "col col-md-6">
<div class = "form-group mb-4">
<label for = "select-ins">Interested Universities </label>
<select
v-model = "interest.institute_id"
class = "form-control"
@change = "onChangeUniversity($event)"
>
<option disabled value = "">Select a University</option>
<option
v-for = "institute in institutes"
:key = "institute.id"
:value = "institute.id"
>
{{ institute.institute_name }}
</option>
</select>
</div>
</div>
<div class = "col col-md-6">
<div class = "form-group mb-4">
<label>Interested Course</label>
<select
v-model = "interest.course_id"
class = "form-control"
@change = "onChangeCourse($event)"
>
<option disabled value = "">Select a Course</option>
<option
v-for = "course in courses"
:key = "course.id"
:value = "course.id"
>
{{ course.course_name }}
</option>
</select>
</div>
</div>
<div class = "col col-md-12 text-right">
<div class = "row ml-4">
<div v-show = "index == interests.length - 1">
<button
class = "btn btn-warning mb-2 mr-2 btn-rounded"
@click.prevent = "add"
>
Add
</button>
</div>
<div v-show = "index || (!index && interests.length > 1)">
<button
class = "btn btn-danger mb-2 mr-2 btn-rounded"
@click.prevent = "remove"
>
Remove
</button>
</div>
</div>
</div>
</div>
</div>
</form>
</template>
<script>
export default {
data() {
return {
institutes: [],
courses: [],
interests: [
{
institute_id: "",
course_id: "",
},
],
};
},
mounted() {
axios.get("/institues").then((res) => {
this.institutes = res.data;
});
},
methods: {
onChangeUniversity(event) {
let universityId = event.target.value;
axios.get(`/institute-course/${universityId}`).then((res) => {
this.courses = res.data;
});
},
add() {
this.interests.push({
institute_id: "",
course_id: "",
});
},
remove(index) {
this.interests.splice(index, 1);
},
},
};
</script>
проверить снимок экрана
Да вы правы.
ваша структура данных не сделана гладкой для отображения именно этой функциональности. прямо сейчас ты делаешь это трудным путем. Я объясню в решении, дайте мне секунду.





Давайте начнем с вашего установленного крючка. вы вызываете API, чтобы получить все доступные институты. Все идет нормально. у каждого института есть свой ID, это важно на будущее, давайте иметь это в виду.
теперь вы используете функцию, которая затем будет вызывать событие «изменения», например onChangeUniversity. Это хороший способ предотвратить перегрузку данных на странице, хорошая идея - просто получать данные только тогда, когда они необходимы.
затем следует сложная часть, которая затрудняет чтение вашего кода вам и всем остальным.
у вас есть этот массив courses в ваших данных, который обычно принадлежит соответствующему институту. этот массив не следует обрабатывать как второй массив, кроме институтов, он должен быть его дочерним элементом.
например, проверьте эту структуру данных:
institutes: [
{
institute_name: "WhatEver1",
id: 0,
courses: [{ course: 1 }, { course: 2 }, { course: 3 }],
}
]
вместо этого:
institutes: [
{
institute_name: "WhatEver1",
id: 0,
},
],
courses: [{ course: 1 }, { course: 2 }, { course: 3 }],
Первый вариант выше - хороший вложенный способ отображения данных в виде цикла внутри цикла. Это означает, что вы должны продвигать свои курсы в выбранном вами институте с принадлежащим им идентификатором.
ваша функция onChangeUniversity должна делать что-то вроде этого:
onChangeUniversity(event) {
let universityId = event.target.value;
axios.get(`/institute-course/${universityId}`).then((res) => {
const foundedId = this.institutes.findIndex(institute => institute.id === universityId)
this.institutes[foundedId].courses = res.data
});
},
после этого гораздо проще перебирать и отображать данные внутри параметров. и я уверен, что у вас больше не будет этой проблемы. просто попробуйте сначала и дайте отзыв.
<div class = "form-group mb-4">
<label>Interested Course</label>
<select
v-model = "interest.course_id"
v-if = "institute.courses.length !== 0" <-------HERE
class = "form-control"
@change = "onChangeCourse($event)"
>
<option disabled value = "">Select a Course</option>
<option
v-for = "course in institute.courses"
:key = "course.id"
:value = "course.id"
>
{{ course.course_name }}
</option>
</select>
</div>
вам нужно условие рендеринга, чтобы остановить цикл ваших курсов от повторения, когда внутри нет данных.
также не забудьте дождаться завершения загрузки курсов.
async onChangeUniversity(event) {
let universityId = event.target.value;
await axios.get(`/institute-course/${universityId}`).then((res) => {
this.courses = res.data;
});
},
а также в вашем навесном крючке
async mounted() {
await axios.get("/institues").then((res) => {
this.institutes = res.data;
});
},
если вы все еще боретесь, дайте мне CodeSandbox вашего текущего кода.
Я очень ценю твой ответ. Я уже изменил массив данных, следуя вашим предложениям, но получаю сообщение об ошибке. Я знаю, что это моя ошибка, но если у вас есть для меня какие-то предложения или вы сделаете HTML за меня, я буду рад вам. Спасибо @Deniz prntscr.com/115vdmc
убедитесь, что у вас есть условие рендеринга для цикла ваших курсов. я обновляю ответ.
@Dniz Я очень благодарен вам за то, что вы мне помогли. пожалуйста, проверьте CodeSandbox codeandbox.io/s/country-institute-course-wvjk0?file=/src/…
Итак, если я правильно понял, вам нужно решение, в котором каждое учреждение является объектом массива, а внутри каждого института у вас будет массив объектов с соответствующими курсами? верный?