Reputation: 1585
I have problem with vm.$watch method it can watch a single variable.
I can't make it to watch array elements.
in the example below i can't watch the change on the two select box bellow:
Vue.directive('select', {
twoWay: true,
bind: function() {
var optionsData
var optionsExpression = this.el.getAttribute('options')
if (optionsExpression) {
optionsData = this.vm.$eval(optionsExpression)
}
// initialize select2
var self = this
$(this.el)
.select2({
data: optionsData
})
.on('change', function() {
self.set(this.value)
})
},
update: function(value) {
$(this.el).val(value).trigger('change')
},
unbind: function() {
$(this.el).off().select2('destroy')
}
})
var vm = new Vue({
el: '#el',
data: {
selected: [{
country: 2
}, {
country: 1
}],
options: [{
id: 1,
text: 'USA'
}, {
id: 2,
text: 'UK'
}]
}
})
vm.$watch('selected', function(newvalue, oldval) {
alert('changed: ' + newvalue)
})
select {
min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.12.9/vue.min.js"></script>
<div id="el">
<p>Selected: {{selected[0].country}}</p>
<select v-select="selected[0].country" options="options">
<option value="0">default</option>
</select>
<p>Selected: {{selected[1].country}}</p>
<select v-select="selected[1].country" options="options">
<option value="0">default</option>
</select>
</div>
Upvotes: 0
Views: 790
Reputation: 17246
You need to specify the deep
option on your watch. The array isn't being modified, an object that it contains is being modified.
Vue.directive('select', {
twoWay: true,
bind: function() {
var optionsData
var optionsExpression = this.el.getAttribute('options')
if (optionsExpression) {
optionsData = this.vm.$eval(optionsExpression)
}
// initialize select2
var self = this
$(this.el)
.select2({
data: optionsData
})
.on('change', function() {
self.set(this.value)
})
},
update: function(value) {
$(this.el).val(value).trigger('change')
},
unbind: function() {
$(this.el).off().select2('destroy')
}
})
var vm = new Vue({
el: '#el',
data: {
selected: [{
country: 2
}, {
country: 1
}],
options: [{
id: 1,
text: 'USA'
}, {
id: 2,
text: 'UK'
}]
}
})
vm.$watch('selected', function(newvalue, oldval) {
alert('changed: ' + newvalue)
}, {
deep: true
})
select {
min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.12.9/vue.min.js"></script>
<div id="el">
<p>Selected: {{selected[0].country}}</p>
<select v-select="selected[0].country" options="options">
<option value="0">default</option>
</select>
<p>Selected: {{selected[1].country}}</p>
<select v-select="selected[1].country" options="options">
<option value="0">default</option>
</select>
</div>
Upvotes: 1