Props working properly now (though solution is half mutable)

This commit is contained in:
josdejong 2020-04-27 11:26:17 +02:00
parent 80c7b2814f
commit cf027db855
4 changed files with 93 additions and 50 deletions

View File

@ -8,33 +8,33 @@
export let searchText = '' export let searchText = ''
let json = { let json = {
'array': [1, 2, 3, { // 'array': [1, 2, 3, {
name: 'Item ' + 2, // name: 'Item ' + 2,
id: String(2), // id: String(2),
index: 2, // index: 2,
time: new Date().toISOString(), // time: new Date().toISOString(),
location: { // location: {
latitude: 1.23, // latitude: 1.23,
longitude: 23.44, // longitude: 23.44,
coordinates: [23.44, 1.23] // coordinates: [23.44, 1.23]
}, // },
}], // }],
'boolean': true, 'boolean': true,
'color': '#82b92c', 'color': '#82b92c',
'null': null, 'null': null,
'number': 123, 'number': 123,
'object': {'a': 'b', 'c': 'd', nested: { // 'object': {'a': 'b', 'c': 'd', nested: {
name: 'Item ' + 2, // name: 'Item ' + 2,
id: String(2), // id: String(2),
index: 2, // index: 2,
time: new Date().toISOString(), // time: new Date().toISOString(),
location: { // location: {
latitude: 1.23, // latitude: 1.23,
longitude: 23.44, // longitude: 23.44,
coordinates: [23.44, 1.23] // coordinates: [23.44, 1.23]
}, // },
}}, // }},
'string': 'Hello World' // 'string': 'Hello World'
} }
let uniDirectionalValue = 'test uni directional flow in Svelte'; let uniDirectionalValue = 'test uni directional flow in Svelte';

View File

@ -4,9 +4,8 @@
import { SEARCH_PROPERTY, SEARCH_VALUE } from './search' import { SEARCH_PROPERTY, SEARCH_VALUE } from './search'
import classnames from 'classnames' import classnames from 'classnames'
import { isUrl, valueType } from './utils/typeUtils' import { isUrl, valueType } from './utils/typeUtils'
import { escapeHTML } from './utils/stringUtils' import { escapeHTML } from './utils/stringUtils.js'
import uniqueId from 'lodash/uniqueId.js' import { createUpdateProps } from './utils/updateProps.js'
import remove from 'lodash/remove.js'
export let key = 'root' export let key = 'root'
export let value export let value
@ -18,32 +17,18 @@
const DEFAULT_LIMIT = 10000 const DEFAULT_LIMIT = 10000
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)
function getOrCreateId (childKey) {
if (ids === undefined) {
ids = {}
}
if (ids[childKey] === undefined) {
ids[childKey] = uniqueId()
}
return ids[childKey]
}
// FIXME: this should not be needed, use Svelte notation for looping over an object
let ids = undefined
$: props = type === 'object' $: props = type === 'object'
? Object.keys(value).map(childKey => { ? updateProps(value)
return {
id: getOrCreateId(childKey),
key: childKey
}
})
: undefined : undefined
$: limited = type === 'array' && value.length > limit $: limited = type === 'array' && value.length > limit
@ -88,9 +73,10 @@
} }
}) })
if (ids !== undefined) { const index = props.findIndex(item => item.key === oldChildKey)
ids[newChildKey] = ids[oldChildKey] if (index !== -1) {
delete ids[oldChildKey] // FIXME: make immutable (not possible as long as prevProps is stored in updateProps
props[index].key = newChildKey
} }
onChangeValue(updatedValue, key) onChangeValue(updatedValue, key)

37
src/utils/updateProps.js Normal file
View File

@ -0,0 +1,37 @@
import { isObject } from './typeUtils.js'
import uniqueId from 'lodash/uniqueId.js'
export function createUpdateProps () {
let prevProps = undefined
return function updateProps (value) {
// TODO: optimize. check if value is the same as prevValue, if so, don't do anything
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?
console.log('updateProps', { value, prevProps, props})
Object.keys(value).forEach(key => {
if (!prevKeys.has(key)) {
console.log('add key', key)
props.push({
id: uniqueId(),
key
})
}
})
prevProps = props
return props
} else {
prevProps = undefined
return undefined
}
}
}

View File

@ -0,0 +1,20 @@
import { createUpdateProps } from './updateProps.js'
import { expect } from './testUtils.js' // FIXME: replace jest with mocha tests, or move to jest
const test = it // TODO: replace jest with mocha tests, or move to jest
test('updateProps (1)', () => {
const updateProps = createUpdateProps()
expect(updateProps({b: 2}).map(item => item.key)).toEqual(['b'])
const result2 = updateProps({a: 1, b: 2})
expect(result2.map(item => item.key)).toEqual(['b', 'a'])
expect(result2[0].id).toEqual('1')
})
test('updateProps (2)', () => {
const updateProps = createUpdateProps()
const result1 = updateProps({a: 1, b: 2})
expect(updateProps({a: 1, b: 2})).toEqual(result1)
})