mirror of https://github.com/vuejs/vue.git
Fix inline partial parentNode problem
Directives inside inline partials would get the fragment as the parentNode if they are compiled before the partial is appended to the correct parentNode. Therefore keep the reference of the fragment's childNodes, append it, then compile afterwards fixes the problem.
This commit is contained in:
parent
b63b551439
commit
5f21eed2c9
|
|
@ -343,20 +343,24 @@ CompilerProto.compileNode = function (node) {
|
|||
* Compile a text node
|
||||
*/
|
||||
CompilerProto.compileTextNode = function (node) {
|
||||
|
||||
var tokens = TextParser.parse(node.nodeValue)
|
||||
if (!tokens) return
|
||||
var el, token, directive
|
||||
var el, token, directive, partial, partialId, partialNodes
|
||||
|
||||
for (var i = 0, l = tokens.length; i < l; i++) {
|
||||
token = tokens[i]
|
||||
if (token.key) { // a binding
|
||||
if (token.key.charAt(0) === '>') { // a partial
|
||||
var partialId = token.key.slice(1).trim(),
|
||||
partial = this.getOption('partials', partialId)
|
||||
partialId = token.key.slice(1).trim()
|
||||
partial = this.getOption('partials', partialId)
|
||||
if (partial) {
|
||||
el = partial.cloneNode(true)
|
||||
this.compileNode(el)
|
||||
// save an Array reference of the partial's nodes
|
||||
// so we can compile them AFTER appending the fragment
|
||||
partialNodes = slice.call(el.childNodes)
|
||||
}
|
||||
} else { // a binding
|
||||
} else { // a real binding
|
||||
el = document.createTextNode('')
|
||||
directive = Directive.parse('text', token.key, this, el)
|
||||
if (directive) {
|
||||
|
|
@ -366,7 +370,20 @@ CompilerProto.compileTextNode = function (node) {
|
|||
} else { // a plain string
|
||||
el = document.createTextNode(token)
|
||||
}
|
||||
|
||||
// insert node
|
||||
node.parentNode.insertBefore(el, node)
|
||||
|
||||
// compile partial after appending, because its children's parentNode
|
||||
// will change from the fragment to the correct parentNode.
|
||||
// This could affect directives that need access to its element's parentNode.
|
||||
if (partialNodes) {
|
||||
for (var j = 0, k = partialNodes.length; j < k; j++) {
|
||||
this.compile(partialNodes[j])
|
||||
}
|
||||
partialNodes = null
|
||||
}
|
||||
|
||||
}
|
||||
node.parentNode.removeChild(node)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,15 +8,20 @@
|
|||
<body>
|
||||
|
||||
<div id="usa" v-partial="global"></div>
|
||||
<div id="japan" v-partial="local"></div>
|
||||
<div id="japan">{{> local}}</div>
|
||||
<div id="repeat">{{> repeat}}</div>
|
||||
|
||||
<script type="text/v-template" id="test">
|
||||
<p>{{hi}}!</p>
|
||||
</script>
|
||||
|
||||
<script type="text/v-template" id="repeat-template">
|
||||
<p v-repeat="items">{{title}}</p>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
Vue.config({debug:true})
|
||||
// Vue.config({debug:true})
|
||||
|
||||
// direct usage
|
||||
var china = new Vue({
|
||||
|
|
@ -48,10 +53,20 @@
|
|||
var japan = new Vue({
|
||||
el: '#japan',
|
||||
partials: {
|
||||
local: document.querySelector('#test').innerHTML
|
||||
local: '#test'
|
||||
}
|
||||
})
|
||||
japan.hi = 'こんにちは'
|
||||
|
||||
var repeat = new Vue({
|
||||
el: '#repeat',
|
||||
partials: {
|
||||
repeat: '#repeat-template'
|
||||
},
|
||||
data: {
|
||||
items: [{ title: 'Repeat' }]
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
casper.test.begin('Template', 4, function (test) {
|
||||
casper.test.begin('Templates and Partials', 5, function (test) {
|
||||
|
||||
casper
|
||||
.start('./fixtures/template.html')
|
||||
|
|
@ -7,6 +7,7 @@ casper.test.begin('Template', 4, function (test) {
|
|||
test.assertSelectorHasText('#japan', 'こんにちは', 'local partial')
|
||||
test.assertSelectorHasText('#china', '你好', 'direct option')
|
||||
test.assertSelectorHasText('#hawaii', 'Aloha', 'extend option')
|
||||
test.assertSelectorHasText('#repeat', 'Repeat', 'inline partial with repeat')
|
||||
})
|
||||
.run(function () {
|
||||
test.done()
|
||||
|
|
|
|||
Loading…
Reference in New Issue