Skip to content

Commit 904b905

Browse files
committed
Merge pull request #1818 from karevn/dev
Reverse filters support for v1.0
2 parents ffe5825 + c02bdf2 commit 904b905

File tree

4 files changed

+49
-28
lines changed

4 files changed

+49
-28
lines changed

src/directives/public/for.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ module.exports = {
485485
*/
486486

487487
_postProcess: function (value) {
488+
this.processedValue = value
488489
if (_.isArray(value)) {
489490
return value
490491
} else if (_.isPlainObject(value)) {
@@ -522,9 +523,25 @@ module.exports = {
522523
frag.destroy()
523524
}
524525
}
526+
},
527+
528+
_syncChanges: function (scope, value) {
529+
// two-way sync for v-for alias
530+
var subjectValue = this.filters ? this.processedValue
531+
: this.rawValue
532+
if (scope.$key) { // original is an object
533+
subjectValue[scope.$key] = value
534+
} else {
535+
subjectValue.$set(scope.$index, value)
536+
}
537+
if (this.filters) {
538+
var vm = this._scope || this.vm
539+
var reverseValue = vm._applyFilters(subjectValue,
540+
subjectValue, this.filters, true)
541+
vm.$set(this.expression, reverseValue)
542+
}
525543
}
526544
}
527-
528545
/**
529546
* Helper to find the previous element that is a fragment
530547
* anchor. This is necessary because a destroyed frag's

src/instance/misc.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ exports._applyFilters = function (value, oldValue, filters, write) {
3939
return value
4040
}
4141

42+
exports._syncChanges = function (value, expression) {
43+
// two-way sync for v-for alias
44+
var forContext = this.$forContext
45+
if (forContext && forContext.alias === expression) {
46+
var self = this
47+
forContext._withLock(function () {
48+
forContext._syncChanges(self, value)
49+
})
50+
}
51+
}
52+
4253
/**
4354
* Resolve a component, depending on whether the component
4455
* is defined normally or using an async factory function.

src/watcher.js

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,7 @@ Watcher.prototype.set = function (value) {
143143
)
144144
}
145145
}
146-
// two-way sync for v-for alias
147-
var forContext = scope.$forContext
148-
if (forContext && forContext.alias === this.expression) {
149-
if (forContext.filters) {
150-
process.env.NODE_ENV !== 'production' && _.warn(
151-
'It seems you are using two-way binding on ' +
152-
'a v-for alias (' + this.expression + '), and the ' +
153-
'v-for has filters. This will not work properly. ' +
154-
'Either remove the filters or use an array of ' +
155-
'objects and bind to object properties instead.'
156-
)
157-
return
158-
}
159-
forContext._withLock(function () {
160-
if (scope.$key) { // original is an object
161-
forContext.rawValue[scope.$key] = value
162-
} else {
163-
forContext.rawValue.$set(scope.$index, value)
164-
}
165-
})
166-
}
146+
scope._syncChanges(value, this.expression)
167147
}
168148

169149
/**

test/unit/specs/directives/public/for/for_spec.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -730,19 +730,32 @@ if (_.inBrowser) {
730730
}
731731
})
732732

733-
it('warn v-model on alias with filters', function () {
733+
it('v-model on alias with filters', function (done) {
734734
var vm = new Vue({
735735
el: el,
736736
template:
737-
'<div v-for="item in items | orderBy \'item\'">' +
738-
'<input v-model="item">' +
737+
'<div v-for="item in items | filter">' +
738+
'<input v-model="item">{{item}}' +
739739
'</div>',
740740
data: {
741-
items: ['a', 'b']
741+
items: 'a, b'
742+
},
743+
filters: {
744+
filter: {
745+
read: function (value) { return value.split(', ') },
746+
write: function (value) {
747+
return value.join(', ')
748+
}
749+
}
742750
}
743751
})
744-
trigger(vm.$el.querySelector('input'), 'input')
745-
expect(hasWarned(_, 'It seems you are using two-way binding')).toBe(true)
752+
var input = vm.$el.querySelector('input')
753+
input.value = 'c'
754+
trigger(input, 'input')
755+
_.nextTick(function () {
756+
expect(vm.items).toBe('c, b')
757+
done()
758+
})
746759
})
747760

748761
it('nested track by', function (done) {

0 commit comments

Comments
 (0)