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

call attach/detach hooks for transcluded components inside v-if (fix #684)

Evan You 11 лет назад
Родитель
Сommit
3a9bfff268
2 измененных файлов с 38 добавлено и 0 удалено
  1. 11 0
      src/directives/if.js
  2. 27 0
      test/unit/specs/directives/if_spec.js

+ 11 - 0
src/directives/if.js

@@ -53,6 +53,14 @@ module.exports = {
         ;(this.contentPositions = this.contentPositions || []).push(i)
       }
     }
+    // keep track of any transcluded components contained within
+    // the conditional block. we need to call attach/detach hooks
+    // for them.
+    this.transCpnts =
+      this.vm._transCpnts &&
+      this.vm._transCpnts.filter(function (c) {
+        return el.contains(c.$el)
+      })
   },
 
   update: function (value) {
@@ -87,6 +95,9 @@ module.exports = {
       : vm.$compile(frag)
     transition.blockAppend(frag, this.end, vm)
     this.children = vm._children.slice(originalChildLength)
+    if (this.transCpnts) {
+      this.children = this.children.concat(this.transCpnts)
+    }
     if (this.children.length && _.inDoc(vm.$el)) {
       this.children.forEach(function (child) {
         child._callHook('attached')

+ 27 - 0
test/unit/specs/directives/if_spec.js

@@ -212,5 +212,32 @@ if (_.inBrowser) {
       })
     })
 
+    it('call attach/detach for transcluded components', function (done) {
+      document.body.appendChild(el)
+      var attachSpy = jasmine.createSpy('attached')
+      var detachSpy = jasmine.createSpy('detached')
+      var vm = new Vue({
+        el: el,
+        data: { show: true },
+        template: '<div v-component="outer"><div v-component="transcluded"></div></div>',
+        components: {
+          outer: {
+            template: '<div v-if="$parent.show"><content></content></div>'
+          },
+          transcluded: {
+            template: 'transcluded',
+            attached: attachSpy,
+            detached: detachSpy
+          }
+        }
+      })
+      expect(attachSpy).toHaveBeenCalled()
+      vm.show = false
+      _.nextTick(function () {
+        expect(detachSpy).toHaveBeenCalled()
+        done()
+      })
+    })
+
   })
 }