-
Notifications
You must be signed in to change notification settings - Fork 27k
Closed
Labels
Description
Purpose
A component should be able to read its size and react to it. This is hard because we have to wait until DOM is fully rendered before causing layout and reading its position. (Additionally the browser does not have a resize event on elements)
Mental Model
A component can register a size host event which the framework will call:
- On initial render of the component to supply the initial size information.
- When component size changes.
Component may change size due to:
- Window resize
- Changes to DOM rendering (ie text gets longer cause reflow.)
Algorithm
- dirty check all host elements which have
sizeusingElement.getBoundingClientRect()at the end of digest cycle when:- any DOM rendering occurs (may do pruning if we know that some things are absolutely position, later optimization)
- a Window resize occurs. (orientation on mobile, which should cause a resize)
- Invoke
sizehandler only if the bounding rectangle has changed. - Schedule another
digestbefore end of the turn. (This can be done be creating aPromiseand resolving it within currentdigest.)
Notes
- Other platforms may have this primitives and we don't have to dirty check
- Benefit of having it as event is that we can do proper batching of layouts.
- We can optimize (prune) dirty checking later once we know more about the application structure.
RulerService can now be deleted.- Need to split the
sizeevent andpositionconcern into separate events. - Events:
size: when width/height has changed. (Size changes less often then position)position: when width/height or position changed.visible: when the component is visible on the screen.
Example
@Component({
selector: '...'
})
@View({
template: `
<ul style="overflow: scroll"
(scroll)="onScroll($event.target.scrollTop)"
(size)="onResize($event)" >
<li [style.height.px]="topPadding"></li>
<li *for="var row in visibleRows"></li>
<li [style.height.px]="bottomPadding"></li>
</ul>
`
})
class VirtualScroll {
visibleRows: Array;
topPadding: number;
buttomPadding: number;
onScroll(offset: number) {
// update the visibleRows
}
onResize(rect:Rectangle) {
// compute the number of visible rows.
}
}