Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse filters support for v1.0 #1818

Merged
merged 1 commit into from
Nov 16, 2015
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/directives/public/for.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ module.exports = {
*/

_postProcess: function (value) {
this.processedValue = value
if (_.isArray(value)) {
return value
} else if (_.isPlainObject(value)) {
Expand Down Expand Up @@ -522,9 +523,25 @@ 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: 11 additions & 0 deletions src/instance/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ 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: 1 addition & 21 deletions src/watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,27 +143,7 @@ Watcher.prototype.set = function (value) {
)
}
}
// 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)
}
})
}
scope._syncChanges(value, this.expression)
}

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

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

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