Skip to content

Commit b7c7743

Browse files
committed
Merge branch 'master' into issue-171-adapter-replace
2 parents 100fcc4 + 8af76d1 commit b7c7743

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1113
-504
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ Below is the list of invocable methods of the Adapter API with description and l
181181
|[append](https://dhilt.github.io/ngx-ui-scroll/#/adapter#append-prepend)|(options: {<br>&nbsp;&nbsp;items:&nbsp;any[],<br>&nbsp;&nbsp;eof?:&nbsp;boolean<br>}) <br><br> (items:&nbsp;any&nbsp;&vert;&nbsp;any[], eof?:&nbsp;boolean) &#42;<br><sub>&#42; old signature, deprecated</sub>|Adds items to the end of the uiScroll dataset. If eof parameter is not set, items will be added and rendered immediately, they will be placed right after the last item in the uiScroll buffer. If eof parameter is set to true, items will be added and rendered only if the end of the dataset is reached; otherwise, these items will be virtualized. See also [bof/eof](https://dhilt.github.io/ngx-ui-scroll/#/adapter#bof-eof) demo. |
182182
|[prepend](https://dhilt.github.io/ngx-ui-scroll/#/adapter#append-prepend)|(options: {<br>&nbsp;&nbsp;items:&nbsp;any[],<br>&nbsp;&nbsp;bof?:&nbsp;boolean<br>}) <br><br> (items:&nbsp;any&nbsp;&vert;&nbsp;any[], bof?:&nbsp;boolean) &#42;<br><sub>&#42; old signature, deprecated</sub>|Adds items to the beginning of the uiScroll dataset. If bof parameter is not set, items will be added and rendered immediately, they will be placed right before the first item in the uiScroll buffer. If bof parameter is set to true, items will be added and rendered only if the beginning of the dataset is reached; otherwise, these items will be virtualized. See also [bof/eof](https://dhilt.github.io/ngx-ui-scroll/#/adapter#bof-eof) demo. |
183183
|[check](https://dhilt.github.io/ngx-ui-scroll/#/adapter#check-size)| |Checks if any of current items changed it's size and runs a procedure to provide internal consistency and new items fetching if needed. |
184-
|[remove](https://dhilt.github.io/ngx-ui-scroll/#/adapter#remove)|(predicate:&nbsp;ItemsPredicate)<br><br>type&nbsp;ItemsPredicate&nbsp;=<br>&nbsp;&nbsp;(item: ItemAdapter)&nbsp;=><br>&nbsp;&nbsp;&nbsp;&nbsp;boolean|Removes items from current buffer. Predicate is a function to be applied to every item presently in the buffer. Predicate must return boolean value. If predicate's return value is true, the item will be removed. _Note!_ Current implementation allows to remove only a continuous series of items per call. If you want to remove, say, 5 and 7 items, you should call the remove method twice. Removing a series of items from 5 to 7 could be done in a single call. |
184+
|[remove](https://dhilt.github.io/ngx-ui-scroll/#/adapter#remove)|(options: {<br>&nbsp;&nbsp;predicate?:&nbsp;ItemsPredicate,<br>&nbsp;&nbsp;indexes?:&nbsp;number[],<br>&nbsp;&nbsp;increase?:&nbsp;boolean<br>}) <br><br>(func:&nbsp;ItemsPredicate) &#42;<br><sub>&#42; old signature, deprecated</sub><br><br> type&nbsp;ItemsPredicate&nbsp;=<br>&nbsp;&nbsp;(item: ItemAdapter)&nbsp;=><br>&nbsp;&nbsp;&nbsp;&nbsp;boolean|Removes items form buffer and/or virtually. Predicate is a function to be applied to every item presently in the buffer. Predicate must return a boolean value. If predicate's return value is true, the item will be removed. Alternatively, if _indexes_ array is passed, the items whose indexes match the list will be removed. Only one of the _predicate_ and _indexes_ options is allowed. In case of _indexes_, the deletion is performed also virtually. By default, indexes of the items following the deleted ones are decremented. Instead, if _increase_ is set to _true_, indexes of the items before the removed ones will be increased. |
185185
|[clip](https://dhilt.github.io/ngx-ui-scroll/#/adapter#clip)|(options: {<br>&nbsp;&nbsp;forwardOnly?:&nbsp;boolean,<br>&nbsp;&nbsp;backwardOnly?:&nbsp;boolean<br>})|Removes out-of-viewport items on demand. The direction in which invisible items should be clipped can be specified by passing an options object. If no options is passed (or both properties are set to _true_), clipping will occur in both directions. |
186-
|[insert](https://dhilt.github.io/ngx-ui-scroll/#/adapter#insert)|(options: {<br>&nbsp;&nbsp;items:&nbsp;any[],<br>&nbsp;&nbsp;before?:&nbsp;ItemsPredicate,<br>&nbsp;&nbsp;after?:&nbsp;ItemsPredicate,<br>&nbsp;&nbsp;decrease?:&nbsp;boolean<br>})|Inserts items _before_ or _after_ the one that satisfies the predicate condition. Only one of _before_ and _after_ options is allowed. Indexes increase by default. Decreasing strategy can be enabled via _decrease_ option. |
186+
|[insert](https://dhilt.github.io/ngx-ui-scroll/#/adapter#insert)|(options: {<br>&nbsp;&nbsp;items:&nbsp;any[],<br>&nbsp;&nbsp;before?:&nbsp;ItemsPredicate,<br>&nbsp;&nbsp;after?:&nbsp;ItemsPredicate,<br>&nbsp;&nbsp;decrease?:&nbsp;boolean<br>})|Inserts items _before_ or _after_ the one that presents in the buffer and satisfies the predicate condition. Only one of the _before_ and _after_ options is allowed. Indexes increase by default. Decreasing strategy can be enabled via _decrease_ option. |
187187

188188
Along with the documented API there are some undocumented features that can be treated as experimental. They are not tested enough and might change over time. Some of them can be found on the [experimental tab](https://dhilt.github.io/ngx-ui-scroll/#/experimental) of the demo app.
189189

@@ -193,7 +193,7 @@ All of the Adapter methods return Promise resolving at the moment when the scrol
193193
const { adapter } = this.datasource;
194194
const predicate = ({ $index }) => $index === indexToReplace;
195195
await adapter.relax();
196-
await adapter.remove(predicate);
196+
await adapter.remove({ predicate });
197197
await adapter.insert({ items: [itemToReplace], before: predicate });
198198
console.log('Replacement done');
199199
```

demo/app/samples/adapter/adapter-relax.component.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ export class DemoAdapterRelaxComponent {
3232
text: `async doReplace() {
3333
const { adapter } = this.datasource;
3434
await adapter.relax();
35-
adapter.remove(({ $index }) =>
36-
$index > 4 && $index < 8
37-
);
35+
adapter.remove({
36+
predicate: ({ $index }) => $index > 4 && $index < 8
37+
});
3838
await adapter.relax();
3939
adapter.insert({
4040
items: [{ id: '5*', text: 'item #5 *' }],
41-
after: ({ $index }) => $index === 4 }
42-
);
41+
after: ({ $index }) => $index === 4
42+
});
4343
}
4444
`
45-
}, {
45+
}, {
4646
name: 'Is loading',
4747
text: `relax(cb: Function) {
4848
const { adapter } = this.datasource;
@@ -58,9 +58,9 @@ export class DemoAdapterRelaxComponent {
5858
doReplace() {
5959
const { adapter } = this.datasource;
6060
this.relax(() =>
61-
adapter.remove(({ $index }) =>
62-
$index > 4 && $index < 8
63-
)
61+
adapter.remove({
62+
predicate: ({ $index }) => $index > 4 && $index < 8
63+
})
6464
);
6565
this.relax(() =>
6666
adapter.insert({
@@ -70,14 +70,14 @@ doReplace() {
7070
);
7171
}
7272
`
73-
}, {
73+
}, {
7474
name: 'Callback',
7575
text: `doReplace() {
7676
const { adapter } = this.datasource;
7777
adapter.relax(() =>
78-
adapter.remove(({ $index }) =>
79-
$index > 4 && $index < 8
80-
)
78+
adapter.remove({
79+
predicate: ({ $index }) => $index > 4 && $index < 8
80+
})
8181
);
8282
adapter.relax(() =>
8383
adapter.insert({
@@ -87,21 +87,21 @@ doReplace() {
8787
);
8888
}
8989
`
90-
}, {
90+
}, {
9191
name: 'Return',
9292
text: `async doReplace() {
9393
const { adapter } = this.datasource;
9494
await adapter.relax();
95-
await adapter.remove(({ $index }) =>
96-
$index > 4 && $index < 8
97-
);
95+
await adapter.remove({
96+
predicate: ({ $index }) => $index > 4 && $index < 8
97+
});
9898
adapter.insert({
9999
items: [{ id: '5*', text: 'item #5 *' }],
100100
after: ({ $index }) => $index === 4
101101
});
102102
}
103103
`
104-
}];
104+
}];
105105

106106
isLoadingSample = `
107107
if (!adapter.isLoading) {
@@ -120,9 +120,14 @@ doReplace() {
120120
const { adapter } = this.datasource;
121121
const newItem = { id: '5*', text: 'item #5 *' };
122122
await adapter.relax();
123-
adapter.remove(({ $index }) => $index > 4 && $index < 8);
123+
adapter.remove({
124+
predicate: ({ $index }) => $index > 4 && $index < 8
125+
});
124126
await adapter.relax();
125-
adapter.insert({ items: [newItem], after: ({ $index }) => $index === 4 });
127+
adapter.insert({
128+
items: [newItem],
129+
after: ({ $index }) => $index === 4
130+
});
126131
}
127132

128133
}

demo/app/samples/adapter/adapter-return-value.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class DemoAdapterReturnValueComponent {
2121
}>`;
2222

2323
returnValueSample = `
24-
const { immediate } = await adapter.remove(predicate);
24+
const { immediate } = await adapter.remove({ predicate });
2525
if (immediate) {
2626
console.log('No items were removed');
2727
}`;

demo/app/samples/adapter/check-size.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
In this demo method <em>doCheck</em> is implemented to
2121
</p>
2222
<ul>
23-
<li>change real size of items (from 15 to 25) in DOM;</li>
23+
<li>change real size of 10 items (from 15 to 25) in DOM;</li>
2424
<li>run <em>Adapter.check()</em>;</li>
2525
<li>autoscroll to item that was first visible before change (optionally).</li>
2626
</ul>

demo/app/samples/adapter/check-size.component.ts

Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -84,21 +84,22 @@ datasource = new Datasource ({
8484
}
8585
});
8686
87-
findElement(index: number) {
87+
findElement(index: number): HTMLElement | null {
8888
const viewportElement = document.getElementById(this.demoContext.viewportId);
8989
return viewportElement
9090
? viewportElement.querySelector(\`[data-sid="\${index}"]\`)
9191
: null;
9292
}
9393
9494
doChangeSize() {
95-
const index = Number(this.startIndex - 5);
95+
const DELTA = 5;
96+
const index = Number(this.startIndex - DELTA);
9697
if (!isNaN(index)) {
97-
for (let i = index; i < index + 10; i++) {
98+
for (let i = index; i < index + DELTA * 2; i++) {
9899
const element = this.findElement(i);
99100
if (element) {
100-
(<HTMLElement>element).style.height = this.sizeValue + 'px';
101-
const item = this.data.find(_item => _item.id === i);
101+
element.style.height = this.sizeValue + 'px';
102+
const item = this.data.find(({ id }) => id === i);
102103
if (item) {
103104
item.height = this.sizeValue;
104105
}
@@ -108,41 +109,29 @@ doChangeSize() {
108109
}
109110
110111
autoscroll(index: number) {
111-
const { adapter } = this.datasource;
112-
let isLoadingSubscription: Subscription;
113-
const done = () => isLoadingSubscription && isLoadingSubscription.unsubscribe();
114-
isLoadingSubscription = adapter.isLoading$.subscribe(isLoading => {
115-
if (isLoading) {
116-
return;
117-
}
118-
const element = this.findElement(index);
119-
const viewportElement = document.getElementById(this.demoContext.viewportId);
120-
if (!element || !viewportElement) {
121-
done();
122-
return;
123-
}
124-
const elementTop = element.getBoundingClientRect().top;
125-
const viewportTop = viewportElement.getBoundingClientRect().top;
126-
const toScroll = viewportTop - elementTop;
127-
const diff = viewportElement.scrollTop - toScroll;
128-
if (viewportElement.scrollTop === diff) {
129-
done();
130-
} else {
131-
adapter.fix({ scrollPosition: diff });
132-
if (viewportElement.scrollTop === diff) {
133-
done();
134-
}
135-
}
136-
});
112+
const element = this.findElement(index);
113+
const viewportElement = document.getElementsByClassName('viewport')[0];
114+
if (!element || !viewportElement) {
115+
return;
116+
}
117+
const elementTop = element.getBoundingClientRect().top;
118+
const viewportTop = viewportElement.getBoundingClientRect().top;
119+
const toScroll = viewportTop - elementTop;
120+
const diff = viewportElement.scrollTop - toScroll;
121+
if (viewportElement.scrollTop === diff) {
122+
return;
123+
}
124+
this.datasource.adapter.fix({ scrollPosition: diff });
137125
}
138126
139-
doCheck() {
140-
let firstVisibleIndex;
127+
async doCheck() {
128+
await this.datasource.adapter.relax();
129+
let firstVisibleIndex: number | undefined;
141130
if (this.needAutoscroll) {
142131
firstVisibleIndex = this.datasource.adapter.firstVisible.$index;
143132
}
144133
this.doChangeSize();
145-
this.datasource.adapter.check();
134+
await this.datasource.adapter.check();
146135
if (firstVisibleIndex !== undefined) {
147136
this.autoscroll(firstVisibleIndex);
148137
}
@@ -175,21 +164,22 @@ First visible item's index: {{datasource.adapter.firstVisible.$index}}
175164
}`
176165
}];
177166

178-
findElement(index: number) {
167+
findElement(index: number): HTMLElement | null {
179168
const viewportElement = document.getElementById(this.demoContext.viewportId);
180169
return viewportElement
181170
? viewportElement.querySelector(`[data-sid="${index}"]`)
182171
: null;
183172
}
184173

185174
doChangeSize() {
186-
const index = Number(this.startIndex - 5);
175+
const DELTA = 5;
176+
const index = Number(this.startIndex - DELTA);
187177
if (!isNaN(index)) {
188-
for (let i = index; i < index + 10; i++) {
178+
for (let i = index; i < index + DELTA * 2; i++) {
189179
const element = this.findElement(i);
190180
if (element) {
191-
(<HTMLElement>element).style.height = this.sizeValue + 'px';
192-
const item = this.data.find(_item => _item.id === i);
181+
element.style.height = this.sizeValue + 'px';
182+
const item = this.data.find(({ id }) => id === i);
193183
if (item) {
194184
item.height = this.sizeValue;
195185
}
@@ -199,41 +189,29 @@ First visible item's index: {{datasource.adapter.firstVisible.$index}}
199189
}
200190

201191
autoscroll(index: number) {
202-
const { adapter } = this.datasource;
203-
let isLoadingSubscription: Subscription;
204-
const done = () => isLoadingSubscription && isLoadingSubscription.unsubscribe();
205-
isLoadingSubscription = adapter.isLoading$.subscribe(isLoading => {
206-
if (isLoading) {
207-
return;
208-
}
209-
const element = this.findElement(index);
210-
const viewportElement = document.getElementById(this.demoContext.viewportId);
211-
if (!element || !viewportElement) {
212-
done();
213-
return;
214-
}
215-
const elementTop = element.getBoundingClientRect().top;
216-
const viewportTop = viewportElement.getBoundingClientRect().top;
217-
const toScroll = viewportTop - elementTop;
218-
const diff = viewportElement.scrollTop - toScroll;
219-
if (viewportElement.scrollTop === diff) {
220-
done();
221-
} else {
222-
adapter.fix({ scrollPosition: diff });
223-
if (viewportElement.scrollTop === diff) {
224-
done();
225-
}
226-
}
227-
});
192+
const element = this.findElement(index);
193+
const viewportElement = document.getElementById(this.demoContext.viewportId);
194+
if (!element || !viewportElement) {
195+
return;
196+
}
197+
const elementTop = element.getBoundingClientRect().top;
198+
const viewportTop = viewportElement.getBoundingClientRect().top;
199+
const toScroll = viewportTop - elementTop;
200+
const diff = viewportElement.scrollTop - toScroll;
201+
if (viewportElement.scrollTop === diff) {
202+
return;
203+
}
204+
this.datasource.adapter.fix({ scrollPosition: diff });
228205
}
229206

230-
doCheck() {
231-
let firstVisibleIndex;
207+
async doCheck() {
208+
await this.datasource.adapter.relax();
209+
let firstVisibleIndex: number | undefined;
232210
if (this.needAutoscroll) {
233211
firstVisibleIndex = this.datasource.adapter.firstVisible.$index;
234212
}
235213
this.doChangeSize();
236-
this.datasource.adapter.check();
214+
await this.datasource.adapter.check();
237215
if (firstVisibleIndex !== void 0) {
238216
this.autoscroll(firstVisibleIndex);
239217
}

demo/app/samples/adapter/clip.component.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
<p>
88
<em>Adapter.clip</em> is another <em>Adapter</em> API method
99
allowing to remove out-of-viewport items on demand.
10+
Not to be confused with <em>Adapter.remove</em>, as
11+
this method has no impact on the <em>Datasource</em>.
12+
It just cleans up the DOM.
13+
</p>
14+
<p>
1015
Commonly, the <em>uiScroll</em> runs the clipping procedure
1116
each time new items are fetched after scrolling.
1217
Also, the <em>uiScroll</em> clips old items from a side of the viewport

0 commit comments

Comments
 (0)