'Add' from child to parent
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.
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.
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)
But the problem here is that we risk to end up merging add$ with itself many times
Btw, this assymetry of external adds vs internal removes resembles REST, where POSTs are made on collection's path, and DELETEs on item's
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.
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.
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.