od-virtualscroll icon indicating copy to clipboard operation
od-virtualscroll copied to clipboard

[feature request] Iterable support

Open buu700 opened this issue 7 years ago • 3 comments

Currently vsData is expected to be Observable<any[]>. It'd be useful if it were expanded to support the more general Observable<Iterable<any>>, which would allow it to take such types as ES6 Maps and Sets and Immutable.js data structures.

buu700 avatar Apr 28 '17 23:04 buu700

Just wanted to add, I ended up arriving on a pattern that works pretty well with the current API. I needed a way to access other inputs to my component from within the list items, and the solution I came up with seems to work pretty well while also making the Observable<any[]> vs Observable<Iterable<any>> issue irrelevant.

@Input() public immutableList: List<Thing>;

@Input() public otherInput: string;

public readonly vsData	= new Subject<{
	immutableList: List<Thing>;
	otherInput: string;
}[]>();

public ngOnChanges () : void {
	this.vsData.next(new Array(this.immutableList.size).fill({
		immutableList: this.immutableList,
		otherInput: this.otherInput
	}));
}

public vsEqualsFunc () : boolean {
	return false;
}

---

<od-virtualscroll
	fxFlexFill
	[vsData]='vsData'
	[vsEqualsFunc]='vsEqualsFunc'
	[vsOptions]='vsOptions'
>
	<ng-template let-item let-row='row'>
		<my-list-item
			[thing]='item.immutableList.get(row)'
			[otherInput]='item.otherInput'
		></my-list-item>

		<div *ngIf='(row + 1) === item.messages.size'>
			This is the end of the list.
		</div>
	</ng-template>
</od-virtualscroll>

buu700 avatar May 12 '17 21:05 buu700

Hey, thanks for the update. Ok, it's still a little bit of wrapping but with your pattern you can avoid converting between immut List<any> -> any[]. I will still look into the ES6 iterable interface - I'd imagine that Observable<any[]> | Obervable<Iterable<any>> could be handy.

dinony avatar May 18 '17 07:05 dinony

Cool, sounds good. Iterable<T> is a subset of T[] (if I'm not mistaken), so I think it'll be a fairly small change — you shouldn't need the union type, and the existing logic should continue to work with either no changes or a const arr = typeof iterable === 'array' ? iterable : Array.from(iterable).

re: that pattern, just to clarify, it was really only about making values other than the main list accessible from within the template; resolving the iterable vs array issue was incidental. (I'm not super familiar with <ng-template> though, so it's possible that Angular already provides a more idiomatic way to do this.)

buu700 avatar May 18 '17 14:05 buu700