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

detach container before batch DOM updates for sd-each

Evan You 12 лет назад
Родитель
Сommit
98d1108dd1
2 измененных файлов с 37 добавлено и 2 удалено
  1. 1 2
      TODO.md
  2. 36 0
      src/directives/each.js

+ 1 - 2
TODO.md

@@ -1,6 +1,5 @@
 - sd-partial
-- $index on sd-each VMs
-- transition effects
+- sd-transition
 - component examples
 - tests
 - docs

+ 36 - 0
src/directives/each.js

@@ -92,11 +92,13 @@ module.exports = {
         this.vms = null
         var self = this
         this.mutationListener = function (path, arr, mutation) {
+            self.detach()
             var method = mutation.method
             mutationHandlers[method].call(self, mutation)
             if (method !== 'push' && method !== 'pop') {
                 self.updateIndexes()
             }
+            self.retach()
         }
     },
 
@@ -120,11 +122,18 @@ module.exports = {
         collection.__observer__.on('mutate', this.mutationListener)
 
         // create child-seeds and append to DOM
+        this.detach()
         for (var i = 0, l = collection.length; i < l; i++) {
             this.buildItem(collection[i], i)
         }
+        this.retach()
     },
 
+    /*
+     *  Create a new child VM from a data object
+     *  passing along compiler options indicating this
+     *  is a sd-each item.
+     */
     buildItem: function (data, index) {
         ViewModel = ViewModel || require('../viewmodel')
         var node = this.el.cloneNode(true),
@@ -159,6 +168,9 @@ module.exports = {
         }
     },
 
+    /*
+     *  Update index of each item after a mutation
+     */
     updateIndexes: function () {
         var i = this.vms.length
         while (i--) {
@@ -166,6 +178,30 @@ module.exports = {
         }
     },
 
+    /*
+     *  Detach/ the container from the DOM before mutation
+     *  so that batch DOM updates are done in-memory and faster
+     */
+    detach: function () {
+        var c = this.container,
+            p = this.parent = c.parentNode,
+            n = this.next = c.nextSibling
+        if (p) {
+            p.removeChild(c)
+        }
+    },
+
+    retach: function () {
+        var n = this.next,
+            p = this.parent,
+            c = this.container
+        if (n) {
+            p.insertBefore(c, n)
+        } else {
+            p.appendChild(c)
+        }
+    },
+
     unbind: function () {
         if (this.collection) {
             this.collection.__observer__.off('mutate', this.mutationListener)