Fix changing property name not working for arrays and objects
This commit is contained in:
parent
7646c1756b
commit
3a9a409fcb
|
@ -7,7 +7,7 @@
|
|||
|
||||
export let searchText = ''
|
||||
|
||||
let json = {
|
||||
export let json = {
|
||||
'array': [1, 2, 3, {
|
||||
name: 'Item ' + 2,
|
||||
id: String(2),
|
||||
|
@ -102,7 +102,7 @@
|
|||
}
|
||||
|
||||
function handleChangeValue (value, key) {
|
||||
console.log('App handleChangeValue')
|
||||
console.log('App handleChangeValue', value, key)
|
||||
json = value
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import classnames from 'classnames'
|
||||
import { isUrl, stringConvert, valueType } from './utils/typeUtils'
|
||||
import { escapeHTML } from './utils/stringUtils.js'
|
||||
import { createUpdateProps } from './utils/updateProps.js'
|
||||
import { updateProps } from './utils/updateProps.js'
|
||||
import { unescapeHTML } from './utils/stringUtils'
|
||||
|
||||
export let key = undefined
|
||||
|
@ -18,19 +18,18 @@
|
|||
const DEFAULT_LIMIT = 100
|
||||
const escapeUnicode = false // TODO: pass via options
|
||||
|
||||
// create lazy, memoized updateProps function
|
||||
let updateProps = function lazyUpdateProps (value) {
|
||||
updateProps = createUpdateProps()
|
||||
return updateProps(value)
|
||||
}
|
||||
|
||||
let limit = DEFAULT_LIMIT
|
||||
|
||||
$: type = valueType (value)
|
||||
|
||||
$: props = type === 'object'
|
||||
? updateProps(value)
|
||||
: undefined
|
||||
let prevValue = undefined
|
||||
let props = updateProps(value)
|
||||
|
||||
$: if (value !== prevValue) {
|
||||
prevValue = value
|
||||
|
||||
props = updateProps(value, props)
|
||||
}
|
||||
|
||||
$: limited = type === 'array' && value.length > limit
|
||||
|
||||
|
@ -96,8 +95,15 @@
|
|||
|
||||
const index = props.findIndex(item => item.key === oldChildKey)
|
||||
if (index !== -1) {
|
||||
// FIXME: make immutable (not possible as long as prevProps is stored in updateProps
|
||||
props[index].key = newChildKey
|
||||
// we use splice here to replace the old key with the new new one
|
||||
// already without Svelte noticing it (no assignment), so we prevent
|
||||
// a needless render. We keep the same id, so the child HTML will be
|
||||
// reused
|
||||
// TODO: is there a better way to do this?
|
||||
props.splice(index, 1, {
|
||||
id: props[index].id,
|
||||
key: newChildKey
|
||||
})
|
||||
}
|
||||
|
||||
onChangeValue(updatedValue, key)
|
||||
|
|
|
@ -1,34 +1,26 @@
|
|||
import { isObject } from './typeUtils.js'
|
||||
import uniqueId from 'lodash/uniqueId.js'
|
||||
|
||||
export function createUpdateProps () {
|
||||
let prevProps = undefined
|
||||
export function updateProps (value, prevProps) {
|
||||
if (isObject(value)) {
|
||||
// copy the props that still exist
|
||||
const props = prevProps
|
||||
? prevProps.filter(item => value[item.key] !== undefined)
|
||||
: []
|
||||
|
||||
return function updateProps (value) {
|
||||
// TODO: optimize. check if value is the same as prevValue, if so, don't do anything
|
||||
// add new props
|
||||
const prevKeys = new Set(props.map(item => item.key))
|
||||
Object.keys(value).forEach(key => {
|
||||
if (!prevKeys.has(key)) {
|
||||
props.push({
|
||||
id: uniqueId(),
|
||||
key
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (isObject(value)) {
|
||||
const props = prevProps
|
||||
? prevProps.filter(item => value[item.key] !== undefined) // copy the props that still exist
|
||||
: []
|
||||
|
||||
// process added props
|
||||
const prevKeys = new Set(props.map(item => item.key)) // TODO: this is inefficient, creating a set. cache this set?
|
||||
|
||||
Object.keys(value).forEach(key => {
|
||||
if (!prevKeys.has(key)) {
|
||||
props.push({
|
||||
id: uniqueId(),
|
||||
key
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
prevProps = props
|
||||
return props
|
||||
} else {
|
||||
prevProps = undefined
|
||||
return undefined
|
||||
}
|
||||
return props
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue