2015-07-09 27 views
8

Próbujesz użyć jquery-chosen z vue, problem polega na tym, że ta wtyczka ukrywa faktyczny wybór, który zastosowałem v-model, więc gdy wybiorę wartość, vue nie rozpoznaje go jako wybranej zmiany Zdarzenie i wartość modelu nie są aktualizowane.Zaktualizuj wartość modelu vuejs za pomocą jquery-selected plugin

Wartość zaznaczenia zmienia się faktycznie, gdy coś wybiorę, sprawdziłem to za pomocą pliku console.log, aby zobaczyć wybraną wartość.

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

mogłem zrobić vm.$data.city = $('.cs-select').val(), that wydaje się działać, Ale czy istnieje inna opcja? Jeśli wartość wyboru została zmieniona, dlaczego vue tego nie widzi?

Odpowiedz

2

Odpowiedź: 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: jeszcze lepszym rozwiązaniem (dzięki simplesmiler): http://jsfiddle.net/simplesmiler/qfy6s9Lj/8/

+2

wydaje się, że to nie działa z tagiem select, który ma atrybut multiple (multiselect). –

+0

nie działa z vue 2 – Waqas

3

jestem otwarty na inne propozycje, ale na chwilę obecną zrobiłem to w ten sposób:

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

@ odpowiedź Swift dostał dość blisko, ale jak @bertrand wskazał, że nie działa na multiselects. Zrobiłem coś, co działa w obu przypadkach: http://jsfiddle.net/seanwash/sz8s99xx/

Chciałbym tylko skomentować, ale nie mam wystarczająco dużo rep, aby to zrobić.

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

Jeszcze raz ... Oto aktualizacja (w coffeescript), która zwraca tablicę, jeśli select jest wielokrotnym wyborem i ciągiem, jeśli nie jest: http://jsfiddle.net/seanwash/ wmrkrdzr/1/ –

+0

Każdy pomysł, jak sprawić, by działał z vue2? – Waqas

+0

Nie próbowałem. Korzystam z https://monterail.github.io/vue-multiselect/, który do tej pory był świetny. –

1

zrobiłem aktualizację dla 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"}] 
    } 
}); 

Patrz: https://jsfiddle.net/kaktuspalme/zenksm2b/

+0

Awesome! Dzięki za skrzypce! –

+0

Wydaje się, że nie działa to dla elementów innych niż "wielokrotne". Co to jest "selected: null"? To wydaje się zbędne? A gdzie piszesz 'selected = binding.value', czy nie ustawiasz zmiennej globalnej? –

2

Aktualizacja: Należy pamiętać, to nie działa od wewnątrz v-for pętli. Powiązane z tym pytanie jest dostępne pod adresem here.

Pisali roztworu @ kaktuspalme, a z pomocą mojego przyjaciela Joe Fleming, wymyśliłem rozwiązanie, które działa z Vue 2 i umożliwia jedno- i wielokrotnego wyboru:

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

używać go tak:

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

Działa z multiple="multiple", a nawet ze stanem zagnieżdżonym, np.:

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

Zobacz skrzypce tutaj: https://jsfiddle.net/tylercollier/bvvvgyp0/5/

+0

Thx za rozwiązanie. Działa świetnie. – Postlagerkarte

0

kod zaczerpnięty z @kaktuspalme odpowiedź. Działa teraz z nie-wieloma elementami i tylko dla nie-wielu.

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

Uwagi @Tyler Collier są uwzględniane

Ale ostrożnie, nieruchomości użyć w v-modelu powinna być zdefiniowana jako tablica, na przykład proposalId: [] w przeciwnym razie nie działa