ensure component lifecycle works for components with implicit controllers
This commit is contained in:
parent
7b96a583b3
commit
dbee97bf04
2 changed files with 112 additions and 7 deletions
14
mithril.js
14
mithril.js
|
|
@ -239,10 +239,10 @@ var m = (function app(window, undefined) {
|
|||
}
|
||||
}
|
||||
else if (data != null && dataType === OBJECT) {
|
||||
var controllerConstructors = [], controllers = []
|
||||
var views = [], controllers = []
|
||||
while (data.view) {
|
||||
var controllerConstructor = (data.controller || {}).$original || data.controller || noop
|
||||
var controllerIndex = m.redraw.strategy() == "diff" && cached.controllerConstructors ? cached.controllerConstructors.indexOf(controllerConstructor) : -1
|
||||
var view = data.view.$original || data.view
|
||||
var controllerIndex = m.redraw.strategy() == "diff" && cached.views ? cached.views.indexOf(view) : -1
|
||||
var controller = controllerIndex > -1 ? cached.controllers[controllerIndex] : new (data.controller || noop)
|
||||
var key = data && data.attrs && data.attrs.key
|
||||
data = pendingRequests == 0 || (cached && cached.controllers && cached.controllers.indexOf(controller) > -1) ? data.view(controller) : {tag: "placeholder"}
|
||||
|
|
@ -251,7 +251,7 @@ var m = (function app(window, undefined) {
|
|||
data.attrs.key = key
|
||||
}
|
||||
if (controller.onunload) unloaders.push({controller: controller, handler: controller.onunload})
|
||||
controllerConstructors.push(controllerConstructor)
|
||||
views.push(view)
|
||||
controllers.push(controller)
|
||||
}
|
||||
if (!data.tag && controllers.length) throw new Error("Component template must return a virtual element, not an array, string, etc.")
|
||||
|
|
@ -290,7 +290,7 @@ var m = (function app(window, undefined) {
|
|||
nodes: [node]
|
||||
};
|
||||
if (controllers.length) {
|
||||
cached.controllerConstructors = controllerConstructors
|
||||
cached.views = views
|
||||
cached.controllers = controllers
|
||||
for (var i = 0, controller; controller = controllers[i]; i++) {
|
||||
if (controller.onunload && controller.onunload.$old) controller.onunload = controller.onunload.$old
|
||||
|
|
@ -313,7 +313,7 @@ var m = (function app(window, undefined) {
|
|||
cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs);
|
||||
cached.nodes.intact = true;
|
||||
if (controllers.length) {
|
||||
cached.controllerConstructors = controllerConstructors
|
||||
cached.views = views
|
||||
cached.controllers = controllers
|
||||
}
|
||||
if (shouldReattach === true && node != null) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||
|
|
@ -556,7 +556,7 @@ var m = (function app(window, undefined) {
|
|||
if (arguments.length > 1) args = args.concat([].slice.call(arguments, 1))
|
||||
return component.view.apply(component, args ? [ctrl].concat(args) : [ctrl])
|
||||
}
|
||||
controller.$original = component.controller
|
||||
view.$original = component.view
|
||||
var output = {controller: controller, view: view}
|
||||
if (args[0] && args[0].key != null) output.attrs = {key: args[0].key}
|
||||
return output
|
||||
|
|
|
|||
|
|
@ -1234,6 +1234,111 @@ function testMithril(mock) {
|
|||
|
||||
return redraws1 == 1 && redraws2 == 1
|
||||
})
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
|
||||
var cond = true
|
||||
var controller1 = null, controller2 = null
|
||||
var Root = {
|
||||
view: function() {
|
||||
return cond ? Comp1 : Comp2
|
||||
}
|
||||
}
|
||||
|
||||
var Comp1 = {
|
||||
view: function(ctrl) {
|
||||
controller1 = ctrl
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
var Comp2 = {
|
||||
view: function(ctrl) {
|
||||
controller2 = ctrl
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
m.mount(root, Root)
|
||||
|
||||
mock.requestAnimationFrame.$resolve()
|
||||
|
||||
cond = false
|
||||
m.redraw(true)
|
||||
|
||||
mock.requestAnimationFrame.$resolve()
|
||||
|
||||
return controller1 !== controller2
|
||||
})
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
|
||||
var cond = true
|
||||
var unloaded = false
|
||||
var Root = {
|
||||
view: function() {
|
||||
return cond ? Comp1 : Comp2
|
||||
}
|
||||
}
|
||||
|
||||
var Comp1 = {
|
||||
view: function(ctrl) {
|
||||
return m("div", {config: function(el, init, ctx) {
|
||||
ctx.onunload = function() {unloaded = true}
|
||||
}})
|
||||
}
|
||||
}
|
||||
var Comp2 = {
|
||||
view: function(ctrl) {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
|
||||
m.mount(root, Root)
|
||||
|
||||
mock.requestAnimationFrame.$resolve()
|
||||
|
||||
cond = false
|
||||
m.redraw(true)
|
||||
|
||||
mock.requestAnimationFrame.$resolve()
|
||||
|
||||
return unloaded
|
||||
})
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
|
||||
var cond = true
|
||||
var initialized = null
|
||||
var Root = {
|
||||
view: function() {
|
||||
return cond ? Comp1 : Comp2
|
||||
}
|
||||
}
|
||||
|
||||
var Comp1 = {
|
||||
view: function(ctrl) {
|
||||
return m("div")
|
||||
}
|
||||
}
|
||||
var Comp2 = {
|
||||
view: function(ctrl) {
|
||||
return m("div", {config: function(el, init) {
|
||||
initialized = init
|
||||
}})
|
||||
}
|
||||
}
|
||||
|
||||
m.mount(root, Root)
|
||||
|
||||
mock.requestAnimationFrame.$resolve()
|
||||
|
||||
cond = false
|
||||
m.redraw(true)
|
||||
|
||||
mock.requestAnimationFrame.$resolve()
|
||||
|
||||
return initialized === false
|
||||
})
|
||||
m.redraw.strategy(undefined) //teardown for m.mount tests
|
||||
|
||||
//m.withAttr
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue