transition working with sd-if + sd-repeat (TODO: $destroy)

This commit is contained in:
Evan You 2013-11-06 22:49:42 -05:00 committed by Evan You
parent 8ba58dd795
commit 36da0a783c
7 changed files with 92 additions and 60 deletions

View File

@ -21,6 +21,7 @@
"src/filters.js",
"src/transition.js",
"src/directives/index.js",
"src/directives/if.js",
"src/directives/repeat.js",
"src/directives/on.js",
"src/directives/model.js"

View File

@ -7,6 +7,7 @@ var Emitter = require('./emitter'),
TextParser = require('./text-parser'),
DepsParser = require('./deps-parser'),
ExpParser = require('./exp-parser'),
transition = require('./transition'),
// cache methods
slice = Array.prototype.slice,
@ -22,6 +23,10 @@ function Compiler (vm, options) {
var compiler = this
// indicate that we are intiating this instance
// so we should not run any transitions
compiler.init = true
// extend options
options = compiler.options = options || makeHash()
utils.extend(compiler, options.compilerOptions)
@ -112,6 +117,9 @@ function Compiler (vm, options) {
}
// extract dependencies for computed properties
if (computed.length) DepsParser.parse(computed)
// done!
compiler.init = false
}
var CompilerProto = Compiler.prototype
@ -618,7 +626,9 @@ CompilerProto.destroy = function () {
if (el === document.body) {
el.innerHTML = ''
} else if (el.parentNode) {
el.parentNode.removeChild(el)
transition(el, -1, function () {
el.parentNode.removeChild(el)
})
}
}

View File

@ -131,7 +131,7 @@ function parseFilter (filter, compiler) {
DirProto.update = function (value, init) {
if (!init && value === this.value) return
this.value = value
this.apply(value, init)
this.apply(value)
}
/**
@ -154,12 +154,11 @@ DirProto.refresh = function (value) {
/**
* Actually invoking the _update from the directive's definition
*/
DirProto.apply = function (value, init) {
DirProto.apply = function (value) {
this._update(
this.filters
? this.applyFilters(value)
: value,
init
: value
)
}

57
src/directives/if.js Normal file
View File

@ -0,0 +1,57 @@
var transition = require('../transition')
module.exports = {
bind: function () {
this.parent = this.el.parentNode
this.ref = document.createComment('sd-if-' + this.key)
this.el.sd_ref = this.ref
},
update: function (value) {
var el = this.el,
init = this.compiler.init,
attached = !!el.parentNode
if (!this.parent) { // the node was detached when bound
if (!attached) {
return
} else {
this.parent = el.parentNode
}
}
// should always have this.parent if we reach here
var parent = this.parent,
ref = this.ref
if (!value) {
if (attached) {
// insert the reference node
var next = el.nextSibling
if (next) {
parent.insertBefore(ref, next)
} else {
parent.appendChild(ref)
}
transition(el, -1, remove, init)
}
} else if (!attached) {
transition(el, 1, insert, init)
}
function remove () {
parent.removeChild(el)
}
function insert () {
parent.insertBefore(el, ref)
parent.removeChild(ref)
}
},
unbind: function () {
this.el.sd_ref = null
}
}

View File

@ -1,4 +1,4 @@
var utils = require('../utils'),
var utils = require('../utils'),
transition = require('../transition')
module.exports = {
@ -6,6 +6,7 @@ module.exports = {
on : require('./on'),
repeat : require('./repeat'),
model : require('./model'),
'if' : require('./if'),
attr: function (value) {
this.el.setAttribute(this.arg, value)
@ -50,58 +51,6 @@ module.exports = {
this.el.classList.add(value)
this.lastVal = value
}
},
'if': {
bind: function () {
this.parent = this.el.parentNode
this.ref = document.createComment('sd-if-' + this.key)
this.el.sd_ref = this.ref
},
update: function (value, init) {
var el = this.el,
attached = !!el.parentNode
if (!this.parent) { // the node was detached when bound
if (!attached) {
return
} else {
this.parent = el.parentNode
}
}
// should always have this.parent if we reach here
var parent = this.parent,
ref = this.ref
if (!value) {
if (attached) {
// insert the reference node
var next = el.nextSibling
if (next) {
parent.insertBefore(ref, next)
} else {
parent.appendChild(ref)
}
transition(el, -1, remove, init)
}
} else if (!attached) {
transition(el, 1, insert, init)
}
function remove () {
parent.removeChild(el)
}
function insert () {
parent.insertBefore(el, ref)
parent.removeChild(ref)
}
},
unbind: function () {
this.el.sd_ref = null
}
}
}

View File

@ -2,6 +2,7 @@ var config = require('../config'),
Observer = require('../observer'),
Emitter = require('../emitter'),
utils = require('../utils'),
trans = require('../transition'),
ViewModel // lazy def to avoid circular dependency
/**
@ -159,7 +160,9 @@ module.exports = {
: this.ref
// make sure it works with sd-if
if (!ref.parentNode) ref = ref.sd_ref
ctn.insertBefore(node, ref)
trans(node, 1, function () {
ctn.insertBefore(node, ref)
}, this.compiler.init)
}
// set data on scope and compile

View File

@ -1,4 +1,6 @@
var endEvent = 'transitionend'
var config = require('./config'),
// TODO: sniff proper transitonend event name
endEvent = 'transitionend'
/**
* stage:
@ -8,6 +10,17 @@ var endEvent = 'transitionend'
module.exports = function (el, stage, changeState, init) {
var className = el.sd_transition
// in sd-repeat, the sd-transition directive
// might not have been processed yet
if (!className) {
className = el.getAttribute(config.prefix + '-transition')
}
// TODO: optional duration which
// can override the default transitionend event
// if no transition, just
if (init || !className) {
return changeState()
}