Przeglądaj źródła

unlink transcluded content on destroy

Evan You 11 lat temu
rodzic
commit
635fada44b
3 zmienionych plików z 34 dodań i 33 usunięć
  1. 28 22
      src/compiler/compile.js
  2. 5 7
      src/instance/compile.js
  3. 1 4
      src/instance/init.js

+ 28 - 22
src/compiler/compile.js

@@ -61,31 +61,19 @@ function compile (el, options, partial, transcluded) {
     if (childLinkFn) childLinkFn(source, childNodes, host)
 
     /**
-     * If this is a partial compile, the linker function
-     * returns an unlink function that tearsdown all
-     * directives instances generated during the partial
-     * linking.
+     * The linker function returns an unlink function that
+     * tearsdown all directives instances generated during
+     * the process.
      */
 
-    if (partial && !transcluded) {
-      var selfDirs = vm._directives.slice(originalDirCount)
-      var parentDirs = vm.$parent &&
-        vm.$parent._directives.slice(parentOriginalDirCount)
+    var selfDirs = vm._directives.slice(originalDirCount)
+    var parentDirs = vm.$parent &&
+      vm.$parent._directives.slice(parentOriginalDirCount)
 
-      var teardownDirs = function (vm, dirs) {
-        var i = dirs.length
-        while (i--) {
-          dirs[i]._teardown()
-        }
-        i = vm._directives.indexOf(dirs[0])
-        vm._directives.splice(i, dirs.length)
-      }
-
-      return function unlink () {
-        teardownDirs(vm, selfDirs)
-        if (parentDirs) {
-          teardownDirs(vm.$parent, parentDirs)
-        }
+    return function unlink () {
+      teardownDirs(vm, selfDirs)
+      if (parentDirs) {
+        teardownDirs(vm.$parent, parentDirs)
       }
     }
   }
@@ -99,6 +87,24 @@ function compile (el, options, partial, transcluded) {
   return compositeLinkFn
 }
 
+/**
+ * Teardown a subset of directives on a vm.
+ *
+ * @param {Vue} vm
+ * @param {Array} dirs
+ */
+
+function teardownDirs (vm, dirs) {
+  var i = dirs.length
+  while (i--) {
+    dirs[i]._teardown()
+  }
+  i = vm._directives.indexOf(dirs[0])
+  if (i > -1) {
+    vm._directives.splice(i, dirs.length)
+  }
+}
+
 /**
  * Compile the root element of a component. There are
  * 4 types of things to process here:

+ 5 - 7
src/instance/compile.js

@@ -21,7 +21,7 @@ exports._compile = function (el) {
   if (options._linkFn) {
     // pre-transcluded with linker, just use it
     this._initElement(el)
-    options._linkFn(this, el)
+    this._unlinkFn = options._linkFn(this, el)
   } else {
     // transclude and init element
     // transclude can potentially replace original
@@ -30,7 +30,7 @@ exports._compile = function (el) {
     el = transclude(el, options)
     this._initElement(el)
     // compile and link the rest
-    compile(el, options)(this, el)
+    this._unlinkFn = compile(el, options)(this, el)
     // finally replace original
     if (options.replace) {
       _.replace(original, el)
@@ -110,11 +110,9 @@ exports._destroy = function (remove, deferCleanup) {
     this._children[i].$destroy()
   }
   // teardown all directives. this also tearsdown all
-  // directive-owned watchers. intentionally check for
-  // directives array length on every loop since directives
-  // that manages partial compilation can splice ones out
-  for (i = 0; i < this._directives.length; i++) {
-    this._directives[i]._teardown()
+  // directive-owned watchers.
+  if (this._unlinkFn) {
+    this._unlinkFn()
   }
   // teardown all user watchers.
   var watcher

+ 1 - 4
src/instance/init.js

@@ -44,15 +44,12 @@ exports._init = function (options) {
   this._isReady     =
   this._isAttached  =
   this._isBeingDestroyed = false
+  this._unlinkFn    = null
 
   // children
   this._children = []
   this._childCtors = {}
 
-  // transclusion unlink functions
-  this._containerUnlinkFn =
-  this._contentUnlinkFn = null
-
   // transcluded components that belong to the parent.
   // need to keep track of them so that we can call
   // attached/detached hooks on them.