Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 1 addition & 18 deletions src/directives/public/for.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,6 @@ module.exports = {
*/

_postProcess: function (value) {
this.processedValue = value
if (_.isArray(value)) {
return value
} else if (_.isPlainObject(value)) {
Expand Down Expand Up @@ -523,25 +522,9 @@ module.exports = {
frag.destroy()
}
}
},

_syncChanges: function (scope, value) {
// two-way sync for v-for alias
var subjectValue = this.filters ? this.processedValue
: this.rawValue
if (scope.$key) { // original is an object
subjectValue[scope.$key] = value
} else {
subjectValue.$set(scope.$index, value)
}
if (this.filters) {
var vm = this._scope || this.vm
var reverseValue = vm._applyFilters(subjectValue,
subjectValue, this.filters, true)
vm.$set(this.expression, reverseValue)
}
}
}

/**
* Helper to find the previous element that is a fragment
* anchor. This is necessary because a destroyed frag's
Expand Down
11 changes: 0 additions & 11 deletions src/instance/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ exports._applyFilters = function (value, oldValue, filters, write) {
return value
}

exports._syncChanges = function (value, expression) {
// two-way sync for v-for alias
var forContext = this.$forContext
if (forContext && forContext.alias === expression) {
var self = this
forContext._withLock(function () {
forContext._syncChanges(self, value)
})
}
}

/**
* Resolve a component, depending on whether the component
* is defined normally or using an async factory function.
Expand Down
22 changes: 21 additions & 1 deletion src/watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,27 @@ Watcher.prototype.set = function (value) {
)
}
}
scope._syncChanges(value, this.expression)
// two-way sync for v-for alias
var forContext = scope.$forContext
if (forContext && forContext.alias === this.expression) {
if (forContext.filters) {
process.env.NODE_ENV !== 'production' && _.warn(
'It seems you are using two-way binding on ' +
'a v-for alias (' + this.expression + '), and the ' +
'v-for has filters. This will not work properly. ' +
'Either remove the filters or use an array of ' +
'objects and bind to object properties instead.'
)
return
}
forContext._withLock(function () {
if (scope.$key) { // original is an object
forContext.rawValue[scope.$key] = value
} else {
forContext.rawValue.$set(scope.$index, value)
}
})
}
}

/**
Expand Down
25 changes: 6 additions & 19 deletions test/unit/specs/directives/public/for/for_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -730,32 +730,19 @@ if (_.inBrowser) {
}
})

it('v-model on alias with filters', function (done) {
it('warn v-model on alias with filters', function () {
var vm = new Vue({
el: el,
template:
'<div v-for="item in items | filter">' +
'<input v-model="item">{{item}}' +
'<div v-for="item in items | orderBy \'item\'">' +
'<input v-model="item">' +
'</div>',
data: {
items: 'a, b'
},
filters: {
filter: {
read: function (value) { return value.split(', ') },
write: function (value) {
return value.join(', ')
}
}
items: ['a', 'b']
}
})
var input = vm.$el.querySelector('input')
input.value = 'c'
trigger(input, 'input')
_.nextTick(function () {
expect(vm.items).toBe('c, b')
done()
})
trigger(vm.$el.querySelector('input'), 'input')
expect(hasWarned(_, 'It seems you are using two-way binding')).toBe(true)
})

it('nested track by', function (done) {
Expand Down