-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Template syntax for let bindings #1521
Comments
A reasonably clean alternative would be to map a function over the array and use destructuring in the each loop:
|
That avoids the extra nesting level, but I still find the |
Seems to me that the far better direction here would simply be to use a helper for this sort of situation.
Or, if for some reason you didn't want to perform the operation twice per loop, you could simply setup a computed property and loop over the numbers.
Just my two cents. I think either seem to be a way clearner solution then the nested loop or the inlined map option. |
TOOAWTDI: There's only one (awkward) way to do it. :) |
Generally my experience has been that when you find yourself wanting a feature like this, it's a sign that it's time to break your component up into multiple components: {#each [1,2,3,4] as n}
<Item {n} sqr_n={n * n}/>
{/each} |
@Rich-Harris Could I get your intuition for why that rule of thumb applies to svelte components but not Javascript functions? I tend to make heavy use of |
@girving not one that bears any real scrutiny 😀 It could be nothing more than my mind coming up with ways to justify the absence of variable declarations, because the thought of implementing them scares me. But I'll try: When you write imperative code, you're writing sequences of statements that execute in order. So this... let x = a;
let y = x; ...means something different to this: let y = x;
let x = a; (Feel free to substitute in an example that doesn't involve a TDZ violation if it makes more sense.) In a declarative language like Svelte's HTMLx, you're not writing a program so much as describing a graph. The relationships between the different parts of the graph don't quite map to the relationships between different JavaScript statements. Given that, the semantics of any form of variable declaration would inevitably differ from JavaScript's semantics enough to cause real confusion. I think the only way it would really make sense is if it was another block helper, like this... {#each [1,2,3,4] as n}
{#with sqr_n = n * n}
{sqr_n} {sqr_n/2}<br>
{/with}
{/each} ...but that starts to look a bit unwieldy. When I say that my experience is that it means it's time to split up your components, I guess I mean that there tends to be a logical grouping between all the things that care about (for example) |
I'm imagining this
and the scope implicitly extends as far as appropriate. This differs from your Happy to close if you think this isn't worth the trouble. Similar to Javascript or ocaml it is always possible to replace |
I am using the store to compute 3x arrays on which I am looping like this:
In this case, is the template updated in one loop even if I use 3x different each loops? Having let would allow me to have something like this:
In this case, the code seems more readable to me as I am grouping my data together (But it's true I could create a sub-component that would receive myTasks). |
Yes — changes that happen in the same // results in a single update
store.set({preTasks, tasks, postTasks})
// results in three separate updates
store.set({preTasks})
store.set({tasks})
store.set({postTasks}) Having said that, Svelte does what it can to avoid doing unnecessary work even in the second case; for example when you change |
@Rich-Harris Btw, I lack a little an opportunity to create the internal context without the need for the creation of one more component. My experience is that components count increase very fast in Svelte, much faster than in Ractive. |
For further rationale for wanting something like this (in-block evaluation), see a related issue. Yes, it can be achieved with multiple components (see link), but it is potentially a lot more verbose and messy than it could be with another block. |
yes! this should be the "best practice" here a benchmark shows no difference, at least for small data here is a TreeView component, using {#each Object.entries(object)
.map(([key, val]) => [key, val,
joinPath(path, key), get_pathDot(path)])
as [key, val, keyPath, pathDot]
} it is a bit redundant for large or unknown objects {#each array.map((obj) => Object.assign(
obj, {newProp: obj.a + obj.b}
)) as obj
}
IMO we should add this to the tutorial otherwise the template system looks too limiting IMO svelte does have a responsibility |
@milahu The problem is with something like this, you cannot really achieve the lazy evaluation that I was attempting in the example I linked to. Yes, I suppose it could be done inside the |
here is a solution : D {#each [obj.get(obj)] as val}
val = {val}
{/each} create a "pseudo list" with just one item a // proposal
{#with obj.get(obj) as val}
val = {val}
{/with} the equal sign /*
with block implementation sample
{#with getVal() as val}
local: val = {val}
{/with}
variable shadowing in local scope
val = getVal()
IIFE = Immediately Invoked Function Expression
*/
let val = 'global value'
const getVal = () => 'local value'
const p = (str) => console.log(str)
let res = null
// with Grouping Operator ()
p('1. global val = '+val)
res = ( function (val) {
// block contents
p('2. local val = '+val)
return 'local result 1'
} )(getVal());
p('3. global res = '+res)
p('3. global val = '+val)
// without Grouping Operator ()
res = function (val) {
// block contents
p('4. local val = '+val)
return 'local result 2'
}(getVal())
p('5. global res = '+res)
p('5. global val = '+val) result 1. global val = global value
2. local val = local value
3. global res = local result 1
3. global val = global value
4. local val = local value
5. global res = local result 2
5. global val = global value |
Closing in favour of the |
For anyone coming across this. They have introduced an |
Currently there is no specific syntax to reuse computations that depend on
each
loop variables. For example, here's some code that loops over some numbers and uses the squares of the numbers in two different ways:The inner
each
is a hack to define a reusable computation. It would lovely to have syntax something like this:Besides being easier to read, that syntax has the advantage of not introducing another nesting level. Is there a clean alternative to the second version in current svelte? If not, would this be a reasonable feature to add?
The text was updated successfully, but these errors were encountered: