mirroring function
Closed this issue · 2 comments
It would be really convenient to have a function like my (very, very rough) follow function, which basically just lets one observable list mirror another: https://github.com/jasongrout/jupyter-js-notebook/blob/4cf0e81d019f13bb8992c68b57cc25f4fb5f27bf/src/NotebookWidget.ts#L85
this last thing lets you very easily sync up two lists, so for example, the list of cells automatically maintains the list of widgets with just this: https://github.com/jasongrout/jupyter-js-notebook/blob/4cf0e81d019f13bb8992c68b57cc25f4fb5f27bf/src/NotebookWidget.ts#L45
For completeness, here's my messy, unfinished, rough code:
/* factory is called to create a new sink element from a new source element */
function follow<T,U>(source: IObservableList<T>,
sink: IObservableList<U>,
factory: (arg: T)=> U) {
// Initialize sink list
sink.clear();
for (let i=0; i<source.length; i++) {
sink.add(factory(source.get(i)))
}
source.changed.connect((sender, args) => {
switch(args.type) {
case ListChangeType.Add:
sink.insert(args.newIndex, factory(args.newValue as T))
break;
case ListChangeType.Move:
sink.move(args.oldIndex, args.newIndex);
break;
case ListChangeType.Remove:
sink.removeAt(args.oldIndex);
break;
case ListChangeType.Replace:
sink.replace(args.oldIndex, (args.oldValue as T[]).length,
(args.newValue as T[]).map(factory));
break;
case ListChangeType.Set:
sink.set(args.newIndex, factory(args.newValue as T))
break;
}
});
The use cases for this are going to vary widely, so its unlikely we could make an implementation that satisfies everyone. Closing for now. Will reconsider if it becomes a recurring theme.
Okay. I've already used it twice.