Comments (15)
last renderParent();
call should be parent = renderParent();
instead, right?
from uhtml.
Anyway, this works:
import {render, html} from '//unpkg.com/uhtml?module';
const thing1 = html.for({})`Thing 1`;
const thing2 = html.for({})`Thing 2`;
const renderParent = thing => html`${thing}`;
render(container1, renderParent(thing1));
render(container2, renderParent(thing2));
The issue is that you are moving a "wired" reference around, so that you should not have const parentHtml = html.for({});
but just use html
instead.
This is yet another case I wish I didn't offer html.for
utility, as this use case is not what html.for
should be used for: different containers, different logic ... not sure if I'll ever solve this issue, as it's not a real-world use case to me.
from uhtml.
This is yet another case I wish I didn't offer
html.for
utility, as this use case is not whathtml.for
should be used for: different containers, different logic… not sure if I'll ever solve this issue, as it's not a real-world use case to me.
Please do not remove html.for
. For me it makes a world of difference.
from uhtml.
last renderParent(); call should be parent = renderParent(); instead, right?
Wired references are WeakMapped, so the return value is always the same, which means it doesn't make a difference right?
The issue is that you are moving a "wired" reference around
Sorry, could you explain why moving a wired reference around is a problem? I see the difference, but I can't understand why can't just do render(container, wiredReference)
🙏
from uhtml.
To explain a bit more about my actual use case, my code looks like this:
class MyComponent {
html = html.for(this);
render () {
return this.html`...`;
}
renderTo(container) {
render(container, this.render());
}
}
I want to have a 1-to-1 relationship between each MyComponent
instance and the stuff it renders, so if component.renderTo(container1)
is called and then component.renderTo(container2)
is called later, the results of MyComponent.render
aren't duplicated.
from uhtml.
I won’t remove for but every app based on for only is likely doing something wrong. The for is fir identity only when it matters, it’s not really about referencing everything, from containers to their nodes, and in this case is misused because an empty container is not necessary 99% if the time, as it brings literally no advantages
from uhtml.
Meaning (early comment, sorry), an empty wire solves zero problems and it cannot wire anything … so what is the use case for that empty wire with already wired content?
from uhtml.
I’ve read too late your last comment… it’s a fair use case but I don’t understand why your component would be empty, representing no node. Have you looked at uland, ube, or other components libraries based on uhtml? Anyway, I’ll try to see what’s going on there
from uhtml.
I forgot to say thanks for the help 🙏 – thanks as always for the help!
Let me try to explain why it's empty as best I can. For example, I have a component that renders completely different things depending on its state
class MyComponent {
html = html.for(this);
isOpen = false;
render() {
return this.html`${this.isOpen ? this.renderOpen() : this.renderClosed()}`;
}
renderOpen() {
return html.for(this, "open")`
<style>.container {background: #eee;}</style>
<div class="container">Hi I'm open! <button type="button">Click me</button></div>
`;
}
renderClosed() {
return html.for(this, "closed")`I'm closed now`;
}
open() {
this.isOpen = true;
this.render();
}
close() {
this.isOpen = false;
this.render();
}
renderTo(container) {
render(container, this.render());
}
}
I made another codepen for it too.
With this, I expected to be able to move the return value of MyComponent.render()
around, but at the end both states are on the screen. I think the fact that it's "empty" isn't actually the problem. If I change the template to have some element as the prefix, it still doesn't work. The only way I can make it show the correct content is to wrap the whole thing in a div (this.html`<div>${this.isOpen? ... : ...}</div>`
), although I think having siblings is meant to work.
Have you looked at uland, ube, or other components libraries based on uhtml?
uland yes, ube no, since it looks like I got started before ube came out. I will take a look 👍 .
from uhtml.
I've found the culprit ... basically the issue is that wires are not persistent fragments (as these don't exist, even if I've proposed these centuries ago) ... so while the wire gets updated when no node is used as container, their nodes don't, 'case uhtml by default bypasses wires when it's a single node, plus the differ cannot know if the parentNode of a live node is a wire, as it's bound to its live state on the DOM, not the virtual one.
Heck, dare I say this might be the only case where virtual dom can handle changes better, but to me the main issue is that a component that represent zero nodes is not really a component, and there's no explicit <>...</>
fragment, react like, in uhtml.
It's also possible other libraries are somehow affected by this, but the long story short is that if you don't have a DOM reference that gets moved here and there, the for(...)
fails if its content is a wire (empty template), and its content gets rendered in multiple containers.
For now, I think the solution is to use <div>...</div>
around, or to remember last container and clean it up, or move its nodes once updated.
So ... current wires cannot deal with your use case, and I'm afraid I don't see any easy way to solve this (if any way at all), due lack of persistent fragments in the DOM specifications.
from uhtml.
P.S. I think I'll document this in the README somewhere, but after thinking around this issue, it's probably a won't fix. I'll leave it open until some documentation is in place.
from uhtml.
P.S.2 another issue, if not the only one, is that holes are reflected via comments on render, and if you change container, with an empty template and no container reference, you place two different comments in two different places, so you need a container either ways that represents the container, so that different holes are always related to the same comment, within the component container, explaining pretty much everything we see with these examples.
from uhtml.
I see. I think keeping track of the container isn't possible in my situation, because I'm rendering to a document fragment that gets appended to the document, which brings us back to the problem of non-persistent fragments 🤦
However, I tried to change my codepen to clean up the container just to see if it would work and it still has the same result. I'm still confused about why the "closed" stuff is coming back at all, because after the second render, I don't expect uhtml to retain any references to the result of renderClosed()
.
https://codepen.io/richardkazuomiller/pen/abWxQMN?editors=1111
from uhtml.
to whom it might concern, there is now a real PersistentFragment class that does not mock or mimic a fragment, it literally is a fragment and it returns its parentNode
from the live content so that this issue should've been solved.
The html.for
is now an explicit export from uhtml/keyed
and it's called htmlFor
and it has its counter svgFor
utility for SVG content.
from uhtml.
Closing as there's no reaction whatsoever.
from uhtml.
Related Issues (20)
- Error with Parcel HOT 3
- Recursive fragment w/ lost lastChild during target update HOT 16
- This sequence of renders crashes in both V3 and V4 HOT 15
- Custom Element setters no longer called when uhtml renders them with a direct attribute HOT 9
- Bug? Rendering as dom element broken for 4.4.1, not 4.3.5 HOT 14
- FYI: xeito framework HOT 3
- Question about non-changing interpolated content HOT 7
- Working with inheritance HOT 5
- Renderable type doesn't include valueOf? HOT 5
- Incompatible with TypeScript when moduleResolution === nodenext HOT 6
- v4 error: Cannot set property className of #<SVGElement> which has only a getter HOT 6
- Bug: texContent -> textContent HOT 4
- Small issue with v4 HOT 9
- Cannot render empty array HOT 2
- Clarify CJS usage in v4 / CJS report with v4 HOT 1
- Typescript issues HOT 13
- Consider bringing global `uhtml` export back HOT 1
- Cannot set property list of #<HTMLInputElement> which has only a getter HOT 10
- Functions no longer allowed as Holes? HOT 3
- V4 crashes on empty array HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from uhtml.