Coder Social home page Coder Social logo

Comments (12)

gr0uch avatar gr0uch commented on June 20, 2024

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

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

@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.
So, to update list in this particular case we need to do something like:

state.list.push(...items)
state.isEmpty = state.list.length === 0

Could we use sort of computed property to handle isEmpty state? E.g.

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.
I tried to use Object.defineProperty instead, but this doesn't work for me too.

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 Array it means that to react on update, we need a way to subscribe on its changes (or modify mutation methods) to be able to perform update of isEmpty state.

from simulacra.

gr0uch avatar gr0uch commented on June 20, 2024

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 isEmpty manually. It can still be set manually from outside of the change function, though.

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

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?

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

@daliwali

via the change function

Wow. I thought about something like that. But wasn't sure what it could be so simple :) Thanks!

from simulacra.

gr0uch avatar gr0uch commented on June 20, 2024

E.g. list view and cards view. This views can be different in terms of semantics and accessibility.

In this case, you might need to set isEmpty for both views, this can be extracted into a helper function to be reusable.

Is there any way to remove falsy conditional branches from current DOM?

No, there is not. Even with a template language like Mustache, falsy branches are still in the template.

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

E.g. list view and cards view.

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 state.cards instead of state.list and flush the other one.

I wonder, is there a better way to handle such cases?

from simulacra.

gr0uch avatar gr0uch commented on June 20, 2024

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.

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

@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.

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

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 .view according to currentView state to indicate which data representation should be shown. But if we need to map same item fields to both representations it won't work.

from simulacra.

gr0uch avatar gr0uch commented on June 20, 2024

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()
}

from simulacra.

OEvgeny avatar OEvgeny commented on June 20, 2024

@daliwali Got it. Thank you.

And thanks for sharing simulacra! Keep doing good stuff :)

from simulacra.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.