ractivejs / ractive

Next-generation DOM manipulation
http://ractive.js.org
MIT License
5.94k stars 396 forks source link

How to render surrounding elements conditionally? #3246

Closed ceremcem closed 6 years ago

ceremcem commented 6 years ago

Description:

Do we have a chance to render a partial with or without some surrounding divs conditionally, but without re-rendering the partial? Eg:

{{#if somecase}}
    <div class="xyz">
        {{>myPartial}}
    </div>
{{else}}
    {{>myPartial}}
{{/if}}

It's obvious that I want to show div.xyz around myPartial when somecase occurs. Above code will work, but the problem is that when somecase is falsy then myPartial will render without the surrounding div. When somecase occurs, myPartial will be unrendered and re-rendered with surrounding div.

This will cause performance issues since there are lots of CPU intensive operations are triggered on render of myPartial, so re-rendering causes doubling the operation costs.

fskreuz commented 6 years ago

This trick is easy to do in template systems that just do string interpolation (i.e. Handlebars, Mustache) or string generation, like on servers (i.e. Twig, Django, PHP). But it's different in Ractive because the template is parsed into a tree. The contents of {{#if somecase}} is a different subtree from {{else}}.

If all that matters is class="xyz" and that <div> is harmless when left there, maybe you could just leave the div in there, and just conditionally toggle the class. Similar to how you'd toggle an "active" class for accordions, hovers, collapse, etc. This way, instead of a full subtree re-render, it's just an attribute update.


<div class="{{#if somecase}}xyz{{/if}}">
    {{>myPartial}}
</div>
ceremcem commented 6 years ago

The surrounding div was only an example, real case is much more complicated.

Thinking again, maybe using the ractive.insert() method can help solving the problem.

Inversion-des commented 6 years ago

Maybe decorator can help here. Something like: as-wrapped_if="somecase" and inside the decorator we can add/remove any nodes.

evs-chris commented 6 years ago

As it stands now, this is one of the scenarios that ractive just can't handle. My approach to this sort of thing is usually to leave the wrapper always in place and have the conditional toggle attributes (classes) that make it appear or disappear (border, bgcolor, etc) as necessary.

ceremcem commented 6 years ago

@evs-chris Then I'm closing this issue because it seems a wontfix, at least for now. I'll stick with @fskreuz 's suggestion (as well as yours).