Select2通过ajax初始化筛选项踩坑之殇

今天出现了一个bug,让我深深地再一次鄙视了自己的智商。。。话不多说,记录下自己的二逼,上代码:

Vue.directive('select2', {

    twoWay: true,

    params: ['options'],

    bind: function() {
        var self = this;
        $(this.el).select2(this.params.options).on('change', function() {
            self.set($(this).val());
            //为了清空可能的输入文字
            $(this).siblings('.select2').find('.select2-search__field').val('');
        });
    },

    update: function(value) {
        $(this.el).val(value).trigger('change');
    },

    unbind: function() {
        $(this.el).off().select2('destroy');
    }

});

这是用vue的指令把著名的Select2库进行了包装,为了能够像下面这样愉快的在vue中使用它:

<select  
    v-select2="modiLine" 
    v-bind:options="{}">
    <option v-for="option in modiLineOption"
       v-bind:value="option.id">
        {{ option.name }}
    </option>
 </select>

问题的出现原因是:我用了ajax来得到modiLine的值,并且我用ajax来得到modiLineOption的值

这样一来,两个数据就有个先后顺序了啊。。。。如果option的内容modiLineOption先到,那么一切看起来是正常的,但是如果modiLine先到,则问题出现了。。。经过长时间的debug才发现,如果Select2的option内容为空$(this.el).val(value).trigger('change');传递过去的$(this).val()值为null,即便value是非空的值!!!!!而等option内容modiLineOption的值到达后,Select2并没有保存最近一次改变的value并自动再次为你触发,所以看的初始值一直是空空空。。。。

解决方案: 确保modiLineOption的值已经渲染到dom中,也就是option内容对select2可见,这样再设置modiLine的值才会触发update里的change,而监听change的函数才能正确得到modiLine的值最终更新dom显示出该值seleted。。。。

ps:当出现奇奇怪怪的bug的时候想想是不是ajax异步捣的鬼。。。不要一直纠结api为啥调用的结果不对。。。像这次api调用的结果不对不是api的错,是他对内容有依赖,不过话说回来,如果select2的change api可以支持内容为空时保留最后一次更改的值,待内容不为空时自动为用户触发更新最后一次值得操作就好了。。不过,让我多踩坑也是极好的。

如果我的文章对您有帮助
欢迎打赏(。・ω・)

Zhang Xiao

Read more posts by this author.

beijing