首页 > 解决方案 > Bootstrap-select & Vue.js: selectpicker('refresh') 不工作

问题描述

我正在尝试将 bootstrap-select 插件(在此处找到https://developer.snapappointments.com/bootstrap-select/)实现到使用 Vue.js 作为 javascript 框架的 ruby​​ on rails 应用程序中。

目标是在一个选择中您可以选择一个类别,在另一个选择中您可以选择该类别的所有可用教师。为此,我使用 axios 和 vue 向我自己的 api 发出请求,并使用它来填充第二个选择,它适用于简单的选择字段,但是我希望显示 bootstrap-select,我知道插件有一个函数“selectpicker('refresh')”使选项重新加载成为可能,但我的浏览器控制台声称 selectpicker 不是一个函数,当我在我的 vue 实例上调用它时,我可以在浏览器控制台上手动运行它并且它按预期工作

我的代码:

js:

Vue.use(VueAxios, axios)
    document.addEventListener('DOMContentLoaded', () => {
      if(document.getElementById('enrollment_form')) {
      var app = new Vue({
        el: '#enrollment_form',
        data: {
          CategoryValue: null,
          TeacherValue: null,
          teachers: null,
        },
        methods: {
          fetchTeachers() {
            this.axios.get('/api/teachers/' + this.licenceTypeValue).then(response => (this.teachers = response.data))
              $('.selectpicker').selectpicker('refresh');
          }
        }, 
      })
    }})

看法:

       <div class="row">
          <div class="col-lg-5">
            <div class="form-group">
              <%= f.label :category %>*<br />
              <%= f.collection_select(
                  :category,
                  Category.all,
                  :id,
                  :catgegory_name,
                  {include_blank: true},
                  {
                    class: 'form-control selectpicker',
                    "v-model" => "CategoryValue",
                    "v-on:change" => "fetchTeachers"

                  }
              )%>
            </div>
          </div>  
        </div>

        <div class="row">
          <div class="col-lg-5">
            <div class="form-group">
              <label for="teacher_id">Teacher</label>
              <div>
                <select id="teachers-list" class='form-control selectpicker' v-model="TeacherValue" data-fieldname = "TeacherValue">
                  <option label="" ></option>
                  <option v-for="teacher in teachers" :value="teacher.id"> {{teacher.name}}  </option>
                </select>
              </div>
            </div>
          </div>  
        </div>

        <div>
          <%= f.hidden_field :teacher_id, {"v-model" => "TeacherValue"} %>
        </div>

最后我的 application.js

//= require rails-ujs
//= require activestorage
//= require jquery
//= require jquery_ujs
//= require popper
//= require bootstrap
//= require bootstrap-select

如果有人可以提供帮助,我将不胜感激,因为我根本不知道该怎么做

标签: javascriptvue.jsbootstrap-selectpicker

解决方案


尝试更改为以下内容:

var app = new Vue({
    el: '#enrollment_form',
    data: {
        CategoryValue: null,
        TeacherValue: null,
        teachers: null,
    },
    methods: {
        fetchTeachers() {
            // Get the Vue object in a variable so you can use it in the "then" 
            // since 'this' context changes in the "then" handler function.
            let theVue = this;

            this.axios
                .get('/api/teachers/' + this.licenceTypeValue)
                .then(response => {
                    theVue.teachers = response.data;
                    // Call bootstrap-select's 'refresh' using Vue's $nextTick function 
                    // to ensure the update is complete before bootstrap-select is refreshed.
                    theVue.$nextTick(function(){ $('#teachers-list').selectpicker('refresh'); });
                });
        }
    }, 
})

我在我正在开发的应用程序中遇到了这个问题,并写了一篇更详细的解释文章,包括损坏和工作示例。我的示例通过不带 AJAX 的 JavaScript 更改选项,但概念是相同的。

在上面的代码中,您使用 Vue 的 $nextTick 函数调用 bootstrap-select 'refresh',该函数会等待 Vue 对象的更新完成,然后再执行传递给 $nextTick 调用的代码。(参见Vue 文档中的 $nextTick

注意:您还可以通过添加以下内容在 Vue 的“更新”事件处理程序中进行更通用的更新:

updated: function(){
  this.$nextTick(function(){ $('.selectpicker').selectpicker('refresh'); });
}

请注意,这将始终更新共享同一类“selectpicker”的所有引导选择。每次更新 vue 数据时都会发生更新,包括那些与所讨论的 <select> 无关的数据,这是一种浪费,并且可能会导致性能问题。

我相信最佳做法是仅刷新需要更新的 <select> ,此时它需要刷新(在您的情况下,当 AJAX 调用返回并且“教师”属性已更新时。)


推荐阅读