【问题标题】:Dynamically change select input in Bootstrap Vue在 Bootstrap Vue 中动态更改选择输入
【发布时间】:2021-07-25 23:38:49
【问题描述】:

我正在尝试在通过 JSON 获得的 Bootstrap-Vue 表单选择中设置一些对象。 JSON 由来自以下字段的教师对象组成:

[
  {
    "id": 1,
    "name": "John",
    "surname": "Doe",
    "email": "john.doe@gmail.com"
  }
]

我正在尝试将姓名和姓氏放在选择列表中,即全名。

我已经设法通过计算属性通过处理列表来做到这一点。 但是现在我希望当我选择老师时,根据所选老师过滤课程列表。

为此,我需要教师的电子邮件,但我无法恢复该电子邮件,已处理教师以获得全名。 因此,我什至无法根据所选教师更新课程列表。

这是模板的代码:

<b-form-group
  id="input-group-3"
  label="Docente:"
  label-for="input-3"
>
  <b-form-select
    v-model="teacher"
    :options="teachers"
    value-field="item"
    text-field="fullName"
    required
    @change="filterCourse"
  ></b-form-select>
  <div class="mt-3">
    Selected: <strong>{{ teacher }}</strong>
  </div>
</b-form-group>

这是脚本代码:

import { mapGetters, mapActions } from "vuex";
export default {
  data() {
    return {
      teacher: "",
      course: "",
    };
  },

  created: function() {
    this.GetActiveTeachers();
    this.GetActiveCourses();
  },

  computed: {
    ...mapGetters({
      ActiveTeacherList: "StateActiveTeachers",
      ActiveCourseList: "StateActiveCourses",
      FilteredTeacherList: "StateTeacherByCourse",
      FilteredCourseList: "StateCourseByTeacher",
    }),

    teachers: function() {
      let list = [];
      this.ActiveTeacherList.forEach((element) => {
        let teacher = element.name + " " + element.surname;
        list.push(teacher);
      });
      return list;
    },
  },

  methods: {
    ...mapActions([
      "GetActiveTeachers",
      "GetActiveCourses",
      "GetCourseByTeacher",
      "GetTeacherByCourse",
      "AssignTeaching",
    ]),

    async filterCourse() {
      const Teacher = {
        teacherEmail: "john.doe@gmail.com", // For testing purpose
      };
      try {
        await this.GetCourseByTeacher(Teacher);
      } catch {
        console.log("ERROR");
      }
    },

    async filterTeacher() {
      const Course = {
        title: "Programming", // For testing purpose
      };
      try {
        await this.GetTeacherByCourse(Course);
      } catch {
        console.log("ERROR");
      }
    },
  },
};

【问题讨论】:

    标签: javascript vue.js bootstrap-4 bootstrap-vue


    【解决方案1】:

    您目前正在使用 Bootstrap Vue 为表单选择提供的最简单的表示法,即字符串数组。

    我建议您切换到使用他们的object notation,这将允许您将text(您在列表中显示的内容)与value(发送到选择的v-model)分开指定。

    这样,您将能够访问您需要的教师对象的所有数据,同时仍然能够仅显示您想要的数据。

    我们可以通过将teachers 计算属性中的forEach() 替换为map() 来做到这一点:

    teachers() {
      return this.ActiveTeacherList.map((teacher) => ({
        text: teacher.name + " " + teacher.surname,
        value: teacher
      }));
    },
    

    然后,您需要做的就是更新您的 filterCourse() 处理程序以使用新语法,例如:

    async filterCourse() {
      const Teacher = {
        teacherEmail: this.teacher.email,
      };
      try {
        await this.GetCourseByTeacher(Teacher);
      } catch {
        console.log("ERROR");
      }
    },
    

    最后一点,如果您不想要或不需要完整的对象作为值,那么您可以将它塑造成您需要的任何东西,这就是这种语法的美妙之处。
    例如,您需要全名和电子邮件,而不是部分:

    value: { 
      fullName: teacher.name + " " + teacher.surname,
      email: teacher.email
    }
    

    【讨论】:

    • 为什么会出现这个错误:Error in v-on handler (Promise/async): "TypeError: Cannot read property 'email' of null"?
    • 我的错,select表单中的参数错误
    • 我仍然有一个问题,在应用程序的第一次加载期间courses 计算属性为空,它给了我这个错误:TypeError: Cannot read property 'map' of null。为了避免错误我必须第一次使用选择表单中的数组而不计算它,之后我可以切换到计算数组
    • @Raul 另一种可能的解决方案是将courses 的默认值设为空数组[] 而不是null。这将防止该错误,因为map() 可以有效地调用空数组;它只会返回一个新的空数组。
    • 在计算前解决这个错误我检查数组是否为空,如果为空返回[]
    【解决方案2】:

    您可以执行以下两种不同的选择。

    一种方法是自己在选择中生成&lt;option&gt;,使用v-for 循环您的教师,并将email 属性绑定到value,并显示name 和@ 987654327@在选项里面。

    这将使您的 &lt;b-select&gt; 的 v-model 返回所选教师的电子邮件,然后您可以在过滤器中使用它。

    new Vue({
      el: '#app',
      data() {
        return {
          selectedTeacher: null,
          activeTeachers: [{
              "id": 1,
              "name": "Dickerson",
              "surname": "Macdonald",
              "email": "dickerson.macdonald@example.com"
            },
            {
              "id": 2,
              "name": "Larsen",
              "surname": "Shaw",
              "email": "larsen.shaw@example.com"
            },
            {
              "id": 3,
              "name": "Geneva",
              "surname": "Wilson",
              "email": "geneva.wilson@example.com"
            }
          ]
        }
      }
    })
    <link href="https://unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.css" rel="stylesheet" />
    
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
    <script src="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.js"></script>
    
    
    <div id="app">
      <b-select v-model="selectedTeacher">
        <option v-for="teacher in activeTeachers" :value="teacher.email">
          {{ teacher.name }} {{ teacher.surname }}
        </option>
      </b-select>
    
      {{ selectedTeacher }}
    </div>

    另一种选择是更改您的计算结果以返回一个 objects 数组,而不是像您当前所做的那样返回简单的字符串。

    如果您在 options 属性中使用对象数组,默认情况下 &lt;b-select&gt; 需要属性 value 和 text。

    在这里,您可以将每个教师的 email 绑定到 value,并将 name 和 surname 绑定到 text 属性。

    这将使您的 &lt;b-select&gt; 的 v-model 返回所选教师的电子邮件,然后您可以在过滤器中使用它。

    参考:https://bootstrap-vue.org/docs/components/form-select#options-property

    new Vue({
      el: '#app',
      data() {
        return {
          selectedTeacher: null,
          activeTeachers: [{
              "id": 1,
              "name": "Dickerson",
              "surname": "Macdonald",
              "email": "dickerson.macdonald@example.com"
            },
            {
              "id": 2,
              "name": "Larsen",
              "surname": "Shaw",
              "email": "larsen.shaw@example.com"
            },
            {
              "id": 3,
              "name": "Geneva",
              "surname": "Wilson",
              "email": "geneva.wilson@example.com"
            }
          ]
        }
      },
      computed: {
        teacherOptions() {
          return this.activeTeachers.map(teacher => ({
            value: teacher.email,
            text: `${teacher.name} ${teacher.surname}`
          }));
        }
      }
    })
    <link href="https://unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.css" rel="stylesheet" />
    
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
    <script src="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.js"></script>
    
    
    <div id="app">
      <b-select v-model="selectedTeacher" :options="teacherOptions"></b-select>
    
      {{ selectedTeacher }}
    </div>

    【讨论】:

      猜你喜欢
      • 2013-02-17
      • 2018-11-21
      • 2019-03-03
      • 2021-04-07
      • 2019-04-05
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多