allow mixing keys with non-keyed elements
This commit is contained in:
parent
9554995a1d
commit
8fc5764904
2 changed files with 31 additions and 6 deletions
20
mithril.js
20
mithril.js
|
|
@ -49,7 +49,7 @@ Mithril = m = new function app(window) {
|
||||||
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
||||||
|
|
||||||
var DELETION = 1, INSERTION = 2 , MOVE = 3
|
var DELETION = 1, INSERTION = 2 , MOVE = 3
|
||||||
var existing = {}, shouldMaintainIdentities = false
|
var existing = {}, unkeyed = [], shouldMaintainIdentities = false
|
||||||
for (var i = 0; i < cached.length; i++) {
|
for (var i = 0; i < cached.length; i++) {
|
||||||
if (cached[i] && cached[i].attrs && cached[i].attrs.key !== undefined) {
|
if (cached[i] && cached[i].attrs && cached[i].attrs.key !== undefined) {
|
||||||
shouldMaintainIdentities = true
|
shouldMaintainIdentities = true
|
||||||
|
|
@ -58,15 +58,18 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
if (shouldMaintainIdentities) {
|
if (shouldMaintainIdentities) {
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
if (data[i] && data[i].attrs && data[i].attrs.key !== undefined) {
|
if (data[i] && data[i].attrs) {
|
||||||
var key = data[i].attrs.key
|
if (data[i].attrs.key !== undefined) {
|
||||||
if (!existing[key]) existing[key] = {action: INSERTION, index: i}
|
var key = data[i].attrs.key
|
||||||
else existing[key] = {action: MOVE, index: i, from: existing[key].index, element: parentElement.childNodes[existing[key].index]}
|
if (!existing[key]) existing[key] = {action: INSERTION, index: i}
|
||||||
|
else existing[key] = {action: MOVE, index: i, from: existing[key].index, element: parentElement.childNodes[existing[key].index]}
|
||||||
|
}
|
||||||
|
else unkeyed.push({index: i, element: parentElement.childNodes[i]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var actions = Object.keys(existing).map(function(key) {return existing[key]})
|
var actions = Object.keys(existing).map(function(key) {return existing[key]})
|
||||||
var changes = actions.sort(function(a, b) {return a.action - b.action || b.index - a.index})
|
var changes = actions.sort(function(a, b) {return a.action - b.action || b.index - a.index})
|
||||||
var newCached = new Array(cached.length)
|
var newCached = cached.slice()
|
||||||
|
|
||||||
for (var i = 0, change; change = changes[i]; i++) {
|
for (var i = 0, change; change = changes[i]; i++) {
|
||||||
if (change.action == DELETION) {
|
if (change.action == DELETION) {
|
||||||
|
|
@ -87,6 +90,11 @@ Mithril = m = new function app(window) {
|
||||||
newCached[change.index] = cached[change.from]
|
newCached[change.index] = cached[change.from]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (var i = 0; i < unkeyed.length; i++) {
|
||||||
|
var change = unkeyed[i]
|
||||||
|
parentElement.insertBefore(change.element, parentElement.childNodes[change.index])
|
||||||
|
newCached[change.index] = cached[change.index]
|
||||||
|
}
|
||||||
cached = newCached
|
cached = newCached
|
||||||
cached.nodes = []
|
cached.nodes = []
|
||||||
for (var i = 0, child; child = parentElement.childNodes[i]; i++) cached.nodes.push(child)
|
for (var i = 0, child; child = parentElement.childNodes[i]; i++) cached.nodes.push(child)
|
||||||
|
|
|
||||||
|
|
@ -563,6 +563,23 @@ function testMithril(mock) {
|
||||||
var fourthAfter = root.childNodes[0]
|
var fourthAfter = root.childNodes[0]
|
||||||
return firstBefore === firstAfter && secondBefore === secondAfter && fourthBefore === fourthAfter && root.childNodes[1].key == "10" && root.childNodes[4].key == "6" && root.childNodes[5].key == "7" && root.childNodes.length === 6
|
return firstBefore === firstAfter && secondBefore === secondAfter && fourthBefore === fourthAfter && root.childNodes[1].key == "10" && root.childNodes[4].key == "6" && root.childNodes[5].key == "7" && root.childNodes.length === 6
|
||||||
})
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/149
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, [m("a", {key: 1}), m("a", {key: 2}), m("a"), m("a", {key: 4}), m("a", {key: 5})])
|
||||||
|
var firstBefore = root.childNodes[0]
|
||||||
|
var secondBefore = root.childNodes[1]
|
||||||
|
var thirdBefore = root.childNodes[2]
|
||||||
|
var fourthBefore = root.childNodes[3]
|
||||||
|
var fifthBefore = root.childNodes[4]
|
||||||
|
m.render(root, [m("a", {key: 4}), m("a", {key: 5}), m("a"), m("a", {key: 1}), m("a", {key: 2})])
|
||||||
|
var firstAfter = root.childNodes[3]
|
||||||
|
var secondAfter = root.childNodes[4]
|
||||||
|
var thirdAfter = root.childNodes[2]
|
||||||
|
var fourthAfter = root.childNodes[0]
|
||||||
|
var fifthAfter = root.childNodes[1]
|
||||||
|
return firstBefore === firstAfter && secondBefore === secondAfter && thirdBefore === thirdAfter && fourthBefore === fourthAfter && fifthBefore === fifthAfter
|
||||||
|
})
|
||||||
test(function() {
|
test(function() {
|
||||||
//https://github.com/lhorie/mithril.js/issues/134
|
//https://github.com/lhorie/mithril.js/issues/134
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue