2015-07-09 2 views
8

Попытка использовать jquery-chosen с vue, проблема в том, что этот плагин скрывает фактический выбор, который я применил v-model, поэтому, когда я выбираю значение, vue не распознает его как выбранное изменение значение события и модели не обновляется.Обновление значения модели vuejs с использованием jquery-выбранного плагина

Значение выбора изменяется на самом деле, когда я что-то выбираю, я проверил это с помощью console.log, чтобы увидеть выбранное значение.

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

я мог сделать vm.$data.city = $('.cs-select').val(), that, кажется, работает, Но есть другой вариант? Если значение select было изменено, почему vue не видит этого?

ответ

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"); 

UPDATE: еще лучшее решение (благодаря simplesmiler): http://jsfiddle.net/simplesmiler/qfy6s9Lj/8/

+2

кажется, что это не работает с тегом select, который имеет атрибут множественного (многосегментный). –

+0

не работают с vue 2 – Waqas

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() 
}) 
4

@ ответ Свифта получил довольно близко, но, как @bertrand отметил, что не работает для multiselects. Я работал над тем, что работает в обоих случаях: 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");

+0

Еще раз ... Вот обновление (в coffeescript), которое возвращает массив, если select - это multi select и string, если это не так: http://jsfiddle.net/seanwash/ wmrkrdzr/1/ –

+0

Любая идея о том, как заставить его работать с vue2? – Waqas

+0

Я не пробовал. Я использовал https://monterail.github.io/vue-multiselect/, который до сих пор был замечательным. –

1

Я сделал обновления для 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/

+0

Удивительный! Спасибо за скрипку! –

+0

Это не работает для элементов, отличных от 'множественного'. Кроме того, что такое 'selected: null'? Это кажется лишним? И где вы пишете 'selected = binding.value', разве вы не устанавливаете глобальную переменную? –

2

Update: Советуйте это не работает изнутри v-for цикла. Связанный с этим вопрос, который имеет дело с этим, доступен here.

Уходя из раствора @ kaktuspalme, и с помощью моего друга Джо Флеминга, я придумал решение, которое работает с 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/

+0

Thx для решения. Он отлично работает. – Postlagerkarte

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 учитываются

Но тщательно, свойство используется в ст-модели должен быть определен как массив, например, Заявитель: [] в противном случае он не работает

Смежные вопросы