Просмотр исходного кода

sync v-repeat $value back to original object/array (fix #761)

Evan You 11 лет назад
Родитель
Сommit
e8c36e1fba
2 измененных файлов с 33 добавлено и 0 удалено
  1. 12 0
      src/directives/repeat.js
  2. 21 0
      test/unit/specs/directives/repeat_spec.js

+ 12 - 0
src/directives/repeat.js

@@ -353,6 +353,16 @@ module.exports = {
     if (needCache) {
       this.cacheVm(raw, vm)
     }
+    // sync back changes for $value, particularly for
+    // two-way bindings of primitive values
+    var self = this
+    vm.$watch('$value', function (val) {
+      if (self.converted) {
+        self.rawValue[vm.$key] = val
+      } else {
+        self.rawValue.$set(vm.$index, val)
+      }
+    })
     return vm
   },
 
@@ -537,6 +547,8 @@ function findNextVm (vm, ref) {
  */
 
 function objToArray (obj) {
+  // regardless of type, store the un-filtered raw value.
+  this.rawValue = obj
   if (!isPlainObject(obj)) {
     return obj
   }

+ 21 - 0
test/unit/specs/directives/repeat_spec.js

@@ -603,6 +603,27 @@ if (_.inBrowser) {
       }, 30)
     })
 
+    it('sync $value changes back to original array/object', function (done) {
+      var vm = new Vue({
+        el: el,
+        template:
+          '<div v-repeat="items">{{$value}}</div>' +
+          '<div v-repeat="obj">{{$value}}</div>',
+        data: {
+          items: ['a', 'b'],
+          obj: { foo: 'a', bar: 'b' }
+        }
+      })
+      vm._children[0].$value = 'c'
+      var key = vm._children[2].$key
+      vm._children[2].$value = 'd'
+      _.nextTick(function () {
+        expect(vm.items[0]).toBe('c')
+        expect(vm.obj[key]).toBe('d')
+        done()
+      })
+    })
+
   })
 }