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) {
|
else if (data != null && dataType === OBJECT) {
|
||||||
var controllerConstructors = [], controllers = []
|
var views = [], controllers = []
|
||||||
while (data.view) {
|
while (data.view) {
|
||||||
var controllerConstructor = (data.controller || {}).$original || data.controller || noop
|
var view = data.view.$original || data.view
|
||||||
var controllerIndex = m.redraw.strategy() == "diff" && cached.controllerConstructors ? cached.controllerConstructors.indexOf(controllerConstructor) : -1
|
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 controller = controllerIndex > -1 ? cached.controllers[controllerIndex] : new (data.controller || noop)
|
||||||
var key = data && data.attrs && data.attrs.key
|
var key = data && data.attrs && data.attrs.key
|
||||||
data = pendingRequests == 0 || (cached && cached.controllers && cached.controllers.indexOf(controller) > -1) ? data.view(controller) : {tag: "placeholder"}
|
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
|
data.attrs.key = key
|
||||||
}
|
}
|
||||||
if (controller.onunload) unloaders.push({controller: controller, handler: controller.onunload})
|
if (controller.onunload) unloaders.push({controller: controller, handler: controller.onunload})
|
||||||
controllerConstructors.push(controllerConstructor)
|
views.push(view)
|
||||||
controllers.push(controller)
|
controllers.push(controller)
|
||||||
}
|
}
|
||||||
if (!data.tag && controllers.length) throw new Error("Component template must return a virtual element, not an array, string, etc.")
|
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]
|
nodes: [node]
|
||||||
};
|
};
|
||||||
if (controllers.length) {
|
if (controllers.length) {
|
||||||
cached.controllerConstructors = controllerConstructors
|
cached.views = views
|
||||||
cached.controllers = controllers
|
cached.controllers = controllers
|
||||||
for (var i = 0, controller; controller = controllers[i]; i++) {
|
for (var i = 0, controller; controller = controllers[i]; i++) {
|
||||||
if (controller.onunload && controller.onunload.$old) controller.onunload = controller.onunload.$old
|
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.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs);
|
||||||
cached.nodes.intact = true;
|
cached.nodes.intact = true;
|
||||||
if (controllers.length) {
|
if (controllers.length) {
|
||||||
cached.controllerConstructors = controllerConstructors
|
cached.views = views
|
||||||
cached.controllers = controllers
|
cached.controllers = controllers
|
||||||
}
|
}
|
||||||
if (shouldReattach === true && node != null) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
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))
|
if (arguments.length > 1) args = args.concat([].slice.call(arguments, 1))
|
||||||
return component.view.apply(component, args ? [ctrl].concat(args) : [ctrl])
|
return component.view.apply(component, args ? [ctrl].concat(args) : [ctrl])
|
||||||
}
|
}
|
||||||
controller.$original = component.controller
|
view.$original = component.view
|
||||||
var output = {controller: controller, view: view}
|
var output = {controller: controller, view: view}
|
||||||
if (args[0] && args[0].key != null) output.attrs = {key: args[0].key}
|
if (args[0] && args[0].key != null) output.attrs = {key: args[0].key}
|
||||||
return output
|
return output
|
||||||
|
|
|
||||||
|
|
@ -1234,6 +1234,111 @@ function testMithril(mock) {
|
||||||
|
|
||||||
return redraws1 == 1 && redraws2 == 1
|
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.redraw.strategy(undefined) //teardown for m.mount tests
|
||||||
|
|
||||||
//m.withAttr
|
//m.withAttr
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue