-
Notifications
You must be signed in to change notification settings - Fork 399
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
fix(template-compiler): omit api_key for key outside iteration #2699
Conversation
// iteration, leading to a situation where static children have different keys. | ||
unmount(n1, parent, true); | ||
mount(n2, parent, anchor); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is now unnecessary! And we have a test to prove it.
Previous discussion: #2677 (comment)
b03e79f
to
6969d97
Compare
This comment was marked as outdated.
This comment was marked as outdated.
element.directives.push( | ||
ast.keyDirective(keyAttribute.value, keyAttribute.location, parentIsIteration) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it makes sense to keep the key
directive as part of the AST if it doesn't carry any semantic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Fixed.
const parentIsIteration = !!(forOfParent || forEachParent); | ||
|
||
if (!parentIsIteration) { | ||
ctx.warnAtLocation( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use warnOnNode
instead of warnAtLocation
this would avoid having to pass the parse5ElmLocation
.
ctx.warnAtLocation( | |
ctx.warnOnNode( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the tip! Fixed.
❌ An unexpected error occurred while attempting to start the |
/nucleus test |
1 similar comment
/nucleus test |
|
So, it turns out there was a big use case we missed here – inline iterators and <x-foo iterator:x={items} key={x.value} index={x.index} last={x.last} first={x.first}></x-foo> <x-foo for:each={items} for:item="item" key={item.id}></x-foo> In this case, the |
function isInIteratorElement(ctx: ParserCtx, parent: ParentNode): boolean { | ||
return !!(getForOfParent(ctx, parent) || getForEachParent(ctx)); | ||
function isInIteratorElement(ctx: ParserCtx): boolean { | ||
return !!(getForOfParent(ctx) || getForEachParent(ctx)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmsjtu @pmdartus This part was really tricky – we had slightly different logic for getForOfParent
and getForEachParent
. It was causing getForOfParent
not to work with inline iterators, because I was ignoring the key
in that case.
I guess this didn't matter much before, because these tests were just looking for an error case (keys should not reference the index, or iteration missing a key entirely).
In my fix, we don't care if the for:each
or iterator:x
is on the same node or the parent node. I'd appreciate if you took a look to make sure I didn't miss something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...Just confirmed that it's possible to use an index
as a key
if the iterator
is inline. My PR fixes this.
I can open it as a separate PR if you prefer. This one is getting pretty complex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened a separate PR: #2703
}); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test passes in master
. On 236 (v2.5.13) and 234 (v2.2.12), it throws an error:
Error: Invariant Violation: Compiler should produce html functions that always return an array.
The reason for the error is that the tmpl
function is returning api_custom_element
rather than api_iterator
. So it looks like previously we didn't actually support inline iterators, only inline for:each
.
82e777a
to
2588474
Compare
Details
Partially addresses #2697.
The idea is that if a template is like this:
Then we should not render it with
api_key
, but instead ignore thekey
.How we currently render it:
This PR:
This PR also emits a warning if we find a
key
outside of an iteration.Does this pull request introduce a breaking change?
Does this pull request introduce an observable change?
Almost everyone using a
key
outside of an iteration is probably doing it as a mistake, and even if they are, it should only impact the internals of our vnode-diffing engine.GUS work item
W-10720220