collection icon indicating copy to clipboard operation
collection copied to clipboard

'Add' from child to parent

Open staltz opened this issue 9 years ago • 7 comments

Here's a question or something to consider. I was staring at the Collection API and thinking about the 3rd parameter, add$. It assumes the add events are given from the parent to the collection of children. What if a child component has an add button that would create a neighbor on the list? How do we handle that?

Maybe with the handlers/reducer API this would have been simple: just specify the reducer when an event is emitted on item.add$. Perhaps the handler/reducer API could remain as a generic solution? And another thing to consider is a reducerSelector argument:

const parentAdd$ = ......;

const items$ = Collection(Item, sources, function reducerSelector(item) {
  const addReducer$ = xs.merge(
    item.add$.map(......),
    parentAdd$.map(......)
  );
  const removeReducer$ = item.remove$.map(......);
  const reducer$ = xs.merge(addReducer$, removeReducer$);
  return reducer$; 
});

Just exploratory suggestions.

staltz avatar Jun 23 '16 17:06 staltz

Definitely something worth considering, and the sinks -> stream selector approach has been great so far.

Can you think of an example of a real world application where this functionality might be needed? It's easier to solve problems when they're less abstract.

Widdershin avatar Jun 24 '16 00:06 Widdershin

Maybe even separate addSelector and removeSelector?

const parentAdd$ = ......;

const items$ = Collection(Item, sources, item =>
  xs.merge(
    item.add$,
    parentAdd$
  ), item => item.remove$
});

Then current examples just change to Collection(Item, sources, _ => add$, removeSelector)

Hypnosphi avatar Jun 24 '16 09:06 Hypnosphi

But the problem here is that we risk to end up merging add$ with itself many times

Hypnosphi avatar Jun 24 '16 09:06 Hypnosphi

Btw, this assymetry of external adds vs internal removes resembles REST, where POSTs are made on collection's path, and DELETEs on item's

Hypnosphi avatar Jun 24 '16 09:06 Hypnosphi

Can you think of an example of a real world application where this functionality might be needed? It's easier to solve problems when they're less abstract.

Any list of stuff where an item has a "duplicate this" button. Seems quite common. :)

Maybe even separate addSelector and removeSelector?

That may work! We could experiment.

staltz avatar Jun 25 '16 15:06 staltz

Any list of stuff where an item has a "duplicate this" button.

I second this. I currently have a use case for it, where I have a tree structure wherein the branches and leaves can be duplicated.

UrKr avatar Sep 28 '16 17:09 UrKr

This can be achieved using imitate.

const duplicateProxy$ = xs.create();
const addClick$ = DOM.select('foo').events('click').mapTo({});

const add$ = xs.merge(
  addClick$,
  duplicateProxy$
);

const items$ = Collection(Item, sources, add$);

const duplicate$ = Collection.merge(item => item.duplicate$);
duplicateProxy$.imitate(duplicate$);

Although, I personally prefer to pull any circular deps into the library itself.

It also seems like this could be supported by allowing a function to be passed in place of add$, like item => xs.merge(item.duplicate$, add$). Similar to removal. This seems like a complex and confusing abstraction though.

Widdershin avatar Nov 22 '16 04:11 Widdershin