Closed smackesey closed 5 years ago
Hey Sean,
Thanks for the issue / request.
So I specifically didn't include indexes as part of the original spec, as they are subject to change, so my assumption was that it could cause more issues than it solves, but a few people have mentioned they would like those.
Of course, as you say, indices can only be derived at runtime, so that wouldn't work because the helpers and path syntax require the values compile time.
sync("panelStates/${this.panelIndex}/config") // error! there is no this at compile time
There is at least one ticket out asking for a dynamic this
reference, so I wonder if this might be tied in? For example:
sync("panelStates/:panelIndex/config")
Clearly, the helper would need to build this path dynamically.
Can you try the following sync()
replacement out and see how you get on?
/**
* Updated sync helper to resolve tokens
*
* @param {string} path A path with optional tokens, i.e. `panelStates/:panelIndex/config`
*/
function sync (path) {
return {
get () {
return this.$store.get(resolve(path, this))
},
set (val) {
this.$store.set(resolve(path, this), val)
}
}
}
function resolve (path, scope) {
return path.replace(/:(\w+)/g, function replace (all, token) {
if (!(token in scope)) {
console.error(`Error resolving dynamic store path: The property "${token}" does not exist on the scope`, scope)
}
return scope[token]
})
}
Thanks for the prompt response! To clarify, the ${}
syntax I showed above used double quotes instead of backticks to avoid the immediate interpolation evaluation that would throw the error. The interpolation has to be manually evaluated by the helper; I meant to propose the${}
syntax to have exactly the same functionality as the :
syntax for the dynamic this
reference you suggest (though I like the :
syntax better). Yesterday I wrote some code to do this which is more-or-less equivalent to your code. It's a good sign that multiple people have proposed the same solution.
I will switch over to the code you posted above and see how that works.
Including the code I wrote for reference:
function storePathSubstitute(path, vm) {
return path.replace(/\$\{([^}]+)\}/, (_, x) => vm[x])
}
export function get_dynamic(path) {
return {
get() {
const ipath = storePathSubstitute(path, this)
return this.$store.get(ipath)
}
}
}
export function set_dynamic(path) {
return {
set(val) {
const ipath = storePathSubstitute(path, this)
this.$store.set(ipath, val)
}
}
}
export function sync_dynamic(path) {
return {
get: get_dynamic(path).get,
set: set_dynamic(path).set
}
}
Good stuff!
Yeah – exactly as happened – the template string interpolation in double quotes is ambiguous!
The colon format should already be familiar to anyone using Vue Router.
FYI, these are the related issues:
Arrays:
This:
I used the sync
replacement you posted all day today and I did not encounter any issues.
This would probably be better first posed on a Q/A board since I'm not sure whether Pathify supports this, but I'm not sure where else to post. If what I am asking for is unsupported, consider it a feature request.
I have a number of identical components ("panels") that each have their own copy of some configuration stored in VueX:
The panel components are parameterized with a
panelIndex
prop, which is used to retrieve the correct data from the store. I can't use thesync
component helper because the panel index is not known until runtime, i.e. it's a dynamic part of the store lookup path. So I have to manually specify a getter and setter:Obviously the extra boilerplate is undesirable. It would be better if I could somehow specify the dynamic part of the path in the argument to
sync
, like:Is anything like this possible?