使用jquery-selected插件更新vuejs模型值

时间:2015-07-09 11:10:24

标签: jquery-chosen vue.js

尝试将jquery-chosen与vue一起使用,问题是此插件隐藏了我应用v-model的实际选择,因此当我选择值时,vue不会将其识别为选择更改事件和模型值未更新。

当我选择某些内容时,实际上会更改select的值,我已经使用console.log检查了它,以查看所选的值。

http://jsfiddle.net/qfy6s9Lj/3/

我可以做vm.$data.city = $('.cs-select').val()that似乎有用, 但还有另一种选择吗?如果select的值被更改,为什么vue没有看到这个?

6 个答案:

答案 0 :(得分:4)

@ swift的答案非常接近,但正如@bertrand指出的那样,它对多重选择并不起作用。我已经解决了两种情况:http://jsfiddle.net/seanwash/sz8s99xx/

我会评论,但我没有足够的代表这样做。



Vue.directive('chosen', {
    twoWay: true, // note the two-way binding
    bind: function () {
        $(this.el)
            .chosen({
                inherit_select_classes: true,
                width: '30%',
                disable_search_threshold: 999
            })
            .change(function(ev) {
                // two-way set
                // Construct array of selected options
                var i, len, option, ref;
                var values = [];
                ref = this.el.selectedOptions;
                for (i = 0, len = ref.length; i < len; i++) {
                    option = ref[i];
                    values.push(option.value)
                }
                
                this.set(values);
                
            }.bind(this));
    },
    update: function(nv, ov) {
        // note that we have to notify chosen about update
        $(this.el).trigger("chosen:updated");
    }
});

var vm = new Vue({
  data: {
      city: 'Toronto',
      cities: [{text: 'Toronto', value: 'Toronto'}, 
               {text: 'Orleans', value: 'Orleans'}]
  }
}).$mount("#search-results");
&#13;
&#13;
&#13;

答案 1 :(得分:3)

我开放了其他建议,但是暂时我这样做了:

<强> HTML

<div id='search-results'>
    {{city}}
    <select class="cs-select" v-model='city'>
        <option value="Toronto">Toronto</option>
        <option value="Orleans">Orleans</option>
    </select>
</div>

<强> JS

window.vm = new Vue({
  el: '#search-results',
  data: {
    city: 'Toronto',
  }
})

$('.cs-select').chosen({
    inherit_select_classes: true,
    width: '30%'
}).change( function() {
    vm.$data.city = $('.cs-select').val()
})

答案 2 :(得分:3)

更新:请注意,这不适用于v-for循环。可以使用here来处理相关问题。

离开@ kaktuspalme的解决方案,并在我的朋友Joe Fleming的帮助下,我提出了一个与Vue 2兼容的解决方案,允许单选和多选:

Vue.directive('chosen', {
    inserted: function(el, binding, vnode) {
        jQuery(el).chosen().change(function(event, change) {
            if (Array.isArray(binding.value)) {
                var selected = binding.value;
                if (change.hasOwnProperty('selected')) {
                    selected.push(change.selected);
                } else {
                    selected.splice(selected.indexOf(change.deselected), 1);
                }
            } else {
                var keys = binding.expression.split('.');
                var pointer = vnode.context;
                while (keys.length > 1)
                    pointer = pointer[keys.shift()];
                pointer[keys[0]] = change.selected;
            }
        });
    },
    componentUpdated: function(el, binding) {
        jQuery(el).trigger("chosen:updated");
    }
});

像这样使用:

<select v-model="mymodel" v-chosen="mymodel">...</select>

它适用于multiple="multiple",甚至适用于嵌套状态,例如:

<select v-model="nested.mymodel" v-chosen="nested.mymodel">...</select>

请参阅此处的小提琴:https://jsfiddle.net/tylercollier/bvvvgyp0/5/

答案 3 :(得分:2)

答案: http://jsfiddle.net/qfy6s9Lj/5/

<div id='search-results'>
    Vue model value <br>
    {{city}}
    <hr>
    Select value:
    <select class="cs-select" v-chosen>
       <option value="Toronto">Toronto</option>
       <option value="Orleans">Orleans</option>
    </select>
</div>

Vue.directive('chosen', {
    bind: function () {
        var vm = this.vm;
        this.el.options = vm.cities;
        this.el.value = vm.city;       

        $(this.el).chosen({
            inherit_select_classes: true,
            width: '30%',
            disable_search_threshold: 999})
        .change( function() {
             vm.city = this.el.value;
         }.bind(this)
      );
    }
});

var vm = new Vue({
  data: {
      city: 'Toronto',
      cities: ['Toronto', 'Orleans']
  }
}).$mount("#search-results");

更新:更好的解决方案(感谢simplesmiler): http://jsfiddle.net/simplesmiler/qfy6s9Lj/8/

答案 4 :(得分:2)

我对vue2进行了更新。

Vue.directive('chosen', {
    selected: null,
    inserted: function (el, binding) {
        selected = binding.value;
        $(el).chosen().change(function(event, change) {
            if(change.hasOwnProperty('selected')) {
                selected.push(change.selected);
            } else {
                selected.splice(selected.indexOf(change.deselected), 1);
            }
        });
    },
    componentUpdated: function(el, binding) {
        selected = binding.value;           
        $(el).trigger("chosen:updated");
    }
});

var vm = new Vue({
   el: '#app',
   data: {
      selected: [],
      cities: [{id: 1, value: "Toronto"}, {id: 2, value: "Orleans"}, {id: 3, value: "Bern"}]
   }
});

请参阅:https://jsfiddle.net/kaktuspalme/zenksm2b/

答案 5 :(得分:0)

代码来自@kaktuspalme回答。它现在适用于非多元素,仅适用于非多元素。

 Vue.directive('chosensingle', {

inserted: function (el, binding) {
    var selected = binding.value;

    $(el).chosen().change(function(event, change) {

        if(change.hasOwnProperty('selected')) {
            selected.value = change.selected;                
        } else {
            selected.value  ='';
        }
    });
},
componentUpdated: function(el, binding) {

    $(el).trigger("chosen:updated");
}
});

@Tyler Collier的评论被考虑在内

但要小心,你在v-model中使用的属性应该被定义为数组,例如applicantId:[]否则它不起作用