Closed cfenzo closed 7 years ago
el
is ignored for inline components.All mark this issue as an enhancement so that when we get to progressive rendering (rendering on top of an existing DOM), we can remember to consider this case. Ideally ractive's virtual DOM can be outside of 1:1 with exact DOM tree, but there's some work to get there...
Thanks @martypdx, I thought it was a bit weird (and that el
for components didn't do anything in some previous version)..
I've updated my jsbin: http://jsbin.com/xusez/21/ with a workaround that sets an empty template before moving the component and setting the correct template..
It's a bit fugly, but it'll work until there's a way to set the el
for components :)
I'm about to tackle a similar problem of how to display a popup that needs to be above all the other DOM stuff so it can't live inline with the launching component (I assume that's sortof what's going on for you here).
I think I'll use more of a service approach and run a popup container higher up in the component heirarchy, and use events. I'm using magic: true
, so I'm hoping the data stays in sync without having to call .update()
Yeah, sounds like the same problem. We started off with something along what you describe, but as we write most components as generic as possible (for re-use in a lot of small projects/ad campaigns), having a popup container just didn't fit the bill :)
I also tried to get it working by using a dynamic partial, but the solution I posted turned out to be the one working best for what we needed.
Here's an example dynamic component I'm using now:
component.base = 'board'
component.exports = {
template: function(data){
return '<' + data.board.type + '-board id="' + data.id + '"/>'
}
}
I'll see how it goes with a popup service...
@cfenzo fill under "off-label use", but ractive seems to hold up well just moving the nodes. Here's simple example using component and decorator approach: http://jsfiddle.net/wnwev90g/3/ (different than your workaround in that I'm swapping out DOM nodes, not detaching ractive)
Having spent some time doing this, I agree with @cfenzo that specifying el
on a component should render to that element.
This is my currently implementaton:
component.exports = {
data: {
ready: false
},
oncomplete: function(){
this.detach()
this.host = document.getElementById('drag-host')
this.insert(this.host)
this.set('ready', true)
},
onteardown: function(){
if(this.host) { this.host.innerHTML = '' }
}
}
It seems silly to have to wait (until complete!) then detach and insert. And I have to put a block in the template to prevent flicker on initial render before it gets moved (but still have a root element so something actually renders):
<div>
{{#if ready}}
<!-- actual content -->
{{/if}}
</div>
Seems much better to just render to el
:
component.exports = {
el: document.getElementById('drag-host')
}
Or exploit an option function:
component.exports = {
el: function() {
var host = document.getElementById('drag-host')
if(!host){ /*create it*/ }
return host
}
}
@Rich-Harris Is there any reason why actual DOM nodes shouldn't be loosely coupled with virtualDOM nodes?
In 0.9 builds, you can now attach external instances, that can handle rendering themselves or let the parent instance handle it. That should cover cases like this, where you need manual control but still want to maintain the parent -> child relationship.
Right now, if you set the
el
option for a component, it will render in the element specified (likebody
, or#main
), but crash the whole Ractive instance:I'm not sure if this is a bug, or intended behavior..
Why would you want to render anywhere but where the tag is? one might say.. In some cases, like with a modal or a dropdown, it would be very nice to be able to render the component outside the template (like appended to the body), or outside a list (could be done in more ways).
Rendered Ractive components can be moved outside the template/into any element, by using a combination of
complete
,detach
andinsert
:(jsbin example)[http://jsbin.com/xusez/19] But this workaround will first render the component inside the template (and run all intro animations), and then move the rendered component outside to the specified element. Which can cause glitches..
I hope "rendering components in the element referenced by the
el
option" is a feature worth adding (it looks like it's doable), maybe there should be an option to toggle the behavior?But if components shouldn't be able to render in the
el
, it would be nice if theel
option where ignored for components.