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 = ''
|
export let searchText = ''
|
||||||
|
|
||||||
let json = {
|
export let json = {
|
||||||
'array': [1, 2, 3, {
|
'array': [1, 2, 3, {
|
||||||
name: 'Item ' + 2,
|
name: 'Item ' + 2,
|
||||||
id: String(2),
|
id: String(2),
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChangeValue (value, key) {
|
function handleChangeValue (value, key) {
|
||||||
console.log('App handleChangeValue')
|
console.log('App handleChangeValue', value, key)
|
||||||
json = value
|
json = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { isUrl, stringConvert, valueType } from './utils/typeUtils'
|
import { isUrl, stringConvert, valueType } from './utils/typeUtils'
|
||||||
import { escapeHTML } from './utils/stringUtils.js'
|
import { escapeHTML } from './utils/stringUtils.js'
|
||||||
import { createUpdateProps } from './utils/updateProps.js'
|
import { updateProps } from './utils/updateProps.js'
|
||||||
import { unescapeHTML } from './utils/stringUtils'
|
import { unescapeHTML } from './utils/stringUtils'
|
||||||
|
|
||||||
export let key = undefined
|
export let key = undefined
|
||||||
|
@ -18,19 +18,18 @@
|
||||||
const DEFAULT_LIMIT = 100
|
const DEFAULT_LIMIT = 100
|
||||||
const escapeUnicode = false // TODO: pass via options
|
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
|
let limit = DEFAULT_LIMIT
|
||||||
|
|
||||||
$: type = valueType (value)
|
$: type = valueType (value)
|
||||||
|
|
||||||
$: props = type === 'object'
|
let prevValue = undefined
|
||||||
? updateProps(value)
|
let props = updateProps(value)
|
||||||
: undefined
|
|
||||||
|
$: if (value !== prevValue) {
|
||||||
|
prevValue = value
|
||||||
|
|
||||||
|
props = updateProps(value, props)
|
||||||
|
}
|
||||||
|
|
||||||
$: limited = type === 'array' && value.length > limit
|
$: limited = type === 'array' && value.length > limit
|
||||||
|
|
||||||
|
@ -96,8 +95,15 @@
|
||||||
|
|
||||||
const index = props.findIndex(item => item.key === oldChildKey)
|
const index = props.findIndex(item => item.key === oldChildKey)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
// FIXME: make immutable (not possible as long as prevProps is stored in updateProps
|
// we use splice here to replace the old key with the new new one
|
||||||
props[index].key = newChildKey
|
// 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)
|
onChangeValue(updatedValue, key)
|
||||||
|
|
|
@ -1,34 +1,26 @@
|
||||||
import { isObject } from './typeUtils.js'
|
import { isObject } from './typeUtils.js'
|
||||||
import uniqueId from 'lodash/uniqueId.js'
|
import uniqueId from 'lodash/uniqueId.js'
|
||||||
|
|
||||||
export function createUpdateProps () {
|
export function updateProps (value, prevProps) {
|
||||||
let prevProps = undefined
|
if (isObject(value)) {
|
||||||
|
// copy the props that still exist
|
||||||
|
const props = prevProps
|
||||||
|
? prevProps.filter(item => value[item.key] !== undefined)
|
||||||
|
: []
|
||||||
|
|
||||||
return function updateProps (value) {
|
// add new props
|
||||||
// TODO: optimize. check if value is the same as prevValue, if so, don't do anything
|
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)) {
|
return props
|
||||||
const props = prevProps
|
} else {
|
||||||
? prevProps.filter(item => value[item.key] !== undefined) // copy the props that still exist
|
return undefined
|
||||||
: []
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue