Explorar el Código

fix v-repeat dom manipulation for block instances (fix #799)

Evan You hace 11 años
padre
commit
88c38ce86b
Se han modificado 2 ficheros con 52 adiciones y 7 borrados
  1. 5 2
      src/directives/repeat.js
  2. 47 5
      test/unit/specs/directives/repeat_spec.js

+ 5 - 2
src/directives/repeat.js

@@ -309,17 +309,20 @@ module.exports = {
           vm.$before(ref)
         }
       } else {
+        // make sure to insert before the comment node if
+        // the vms are block instances
+        var nextEl = targetNext._blockStart || targetNext.$el
         if (vm._reused) {
           // this is the vm we are actually in front of
           currentNext = findNextVm(vm, ref)
           // we only need to move if we are not in the right
           // place already.
           if (currentNext !== targetNext) {
-            vm.$before(targetNext.$el, null, false)
+            vm.$before(nextEl, null, false)
           }
         } else {
           // new instance, insert to existing next
-          vm.$before(targetNext.$el)
+          vm.$before(nextEl)
         }
       }
       vm._new = false

+ 47 - 5
test/unit/specs/directives/repeat_spec.js

@@ -314,7 +314,7 @@ if (_.inBrowser) {
       expect(el.innerHTML).toBe('<div>AAA</div><div>BBB</div><div>CCC</div><!--v-repeat-->')
     })
 
-    it('block repeat', function () {
+    it('block repeat', function (done) {
       var vm = new Vue({
         el: el,
         template: '<template v-repeat="list"><p>{{a}}</p><p>{{a + 1}}</p></template>',
@@ -326,10 +326,52 @@ if (_.inBrowser) {
           ]
         }
       })
-      var markup = vm.list.map(function (item) {
-        return '<!--v-start--><p>' + item.a + '</p><p>' + (item.a + 1) + '</p><!--v-end-->'
-      }).join('')
-      expect(el.innerHTML).toBe(markup + '<!--v-repeat-->')
+      assertMarkup()
+      vm.list.reverse()
+      _.nextTick(function () {
+        assertMarkup()
+        done()
+      })
+
+      function assertMarkup () {
+        var markup = vm.list.map(function (item) {
+          return '<!--v-start--><p>' + item.a + '</p><p>' + (item.a + 1) + '</p><!--v-end-->'
+        }).join('')
+        expect(el.innerHTML).toBe(markup + '<!--v-repeat-->')
+      }
+    })
+
+    // added for #799
+    it('block repeat with diff', function (done) {
+      var vm = new Vue({
+        el: el,
+        template: '<template v-repeat="list" v-component="test"></template>',
+        data: {
+          list: [
+            { a: 1 },
+            { a: 2 },
+            { a: 3 }
+          ]
+        },
+        components: {
+          test: {
+            template: '<p>{{a}}</p><p>{{a + 1}}</p>'
+          }
+        }
+      })
+      assertMarkup()
+      vm.list.reverse()
+      _.nextTick(function () {
+        assertMarkup()
+        done()
+      })
+
+      function assertMarkup () {
+        var markup = vm.list.map(function (item) {
+          return '<!--v-start--><p>' + item.a + '</p><p>' + (item.a + 1) + '</p><!--v-end-->'
+        }).join('')
+        expect(el.innerHTML).toBe(markup + '<!--v-repeat-->')
+      }
     })
 
     it('component + parent directive + transclusion', function (done) {