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 DELETION = 1, INSERTION = 2 , MOVE = 3
|
||||
var existing = {}, shouldMaintainIdentities = false
|
||||
var existing = {}, unkeyed = [], shouldMaintainIdentities = false
|
||||
for (var i = 0; i < cached.length; i++) {
|
||||
if (cached[i] && cached[i].attrs && cached[i].attrs.key !== undefined) {
|
||||
shouldMaintainIdentities = true
|
||||
|
|
@ -58,15 +58,18 @@ Mithril = m = new function app(window) {
|
|||
}
|
||||
if (shouldMaintainIdentities) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i] && data[i].attrs && data[i].attrs.key !== undefined) {
|
||||
var key = data[i].attrs.key
|
||||
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]}
|
||||
if (data[i] && data[i].attrs) {
|
||||
if (data[i].attrs.key !== undefined) {
|
||||
var key = data[i].attrs.key
|
||||
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 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++) {
|
||||
if (change.action == DELETION) {
|
||||
|
|
@ -87,6 +90,11 @@ Mithril = m = new function app(window) {
|
|||
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.nodes = []
|
||||
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]
|
||||
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() {
|
||||
//https://github.com/lhorie/mithril.js/issues/134
|
||||
var root = mock.document.createElement("div")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue