Conditional rendering example #61
Comments
The template would contain both the list and the empty view. In your case, the template might look like: <div class="items">
<span class="empty-message"></span>
<div class="item">
<h5 class="name"></h5>
<p class="description"></p>
</div>
</div> Then the state might look like: {
list: [ ... ],
isEmpty: null
} Here's an example of empty/error message in a template: https://github.com/fortunejs/fortune-http/blob/5ee54675e82cebf08b05029b706fa19da2627361/lib/template.html#L116-L117 |
@daliwali Looks interesting. As I understood it means that we have to duplicate some UI related state fields and keep them in sync with existing data. state.list.push(...items)
state.isEmpty = state.list.length === 0 Could we use sort of computed property to handle const state = {
list: [],
get isEmpty () { return this.list.length }
} I tried this approach but it won't work (see this fiddle). Looks like es6 getters are ignored. As I understand the problem is what we have to mutate values directly instead of compute them using getters. It should notify renderer about update. For |
I understand what you mean. The simplest and easiest way to do this is to set it via the change function: function (node, value, previous, path) {
var target = path.target // reference to current object
target.isEmpty = !target.list.length
} This way you don't have to remember to set |
Also there are some cases when keeping both branches of conditional could be problematic. For example when we have two different views of some data and need to switch between them. E.g. list view and cards view. This views can be different in terms of semantics and accessibility. Is there any way to remove falsy conditional branches from current DOM? |
@daliwali
Wow. I thought about something like that. But wasn't sure what it could be so simple :) Thanks! |
In this case, you might need to set
No, there is not. Even with a template language like Mustache, falsy branches are still in the template. |
I was thinking about something like: const state = {
currentView: 'list',
items: [...]
} In state. And template which looks like: <div class="button-toggler">
<!-- toggle views between card and list markup goes here -->
</div>
<div class="list-view">
<div class="item">
<!-- list item markup goes here -->
</div>
</div>
<div class="card-view">
<div class="item">
<!-- card item markup goes here -->
</div>
</div> Sorry that it wasn't so clear from the previous message. Now I understood what this will not work because we couldn't use one array for binding to multiple DOM nodes. To toggle between views we could use something like this in state: const state = {
currentView: 'list',
cards: null,
list: [...] // list will be shown
} To toggle views we simply need to assign items to I wonder, is there a better way to handle such cases? |
Why not just include all of the data in your list, and conditionally hide and show things in CSS? I'm not sure why its necessary to do this in JS at all. |
@daliwali as mentioned before markup could be different especially when semantics and accessibility involved. So, we couldn't just hide or show parts of markup because markup for each data representation (list item and card in this case) could be definitely different. |
Ah, I see another solution for this. We can simplify markup to something like: <div class="button-toggler">
<!-- toggle views between card and list markup goes here -->
</div>
<div class="view">
<div class="item">
<div class="list-view">
<!-- list item markup goes here -->
</div>
<div class="card-view">
<!-- card item markup goes here -->
</div>
</div>
</div> And add classes to |
In your case, I guess having two different lists is unavoidable. You could do something very similar to the example I gave before and modify the second list via the first list's change function: function (node, value, previous, path) {
var target = path.target
target.cards = target.list.slice()
} |
@daliwali Got it. Thank you. And thanks for sharing simulacra! Keep doing good stuff :) |
Imagine we have different markup for empty list and for list which contains elements.
E.g. for empty one we could end up with something like:
And for list with items, markup could be:
How could we use simulacra to deal with such cases? How do you solve conditional rendering problem with it?
The text was updated successfully, but these errors were encountered: