Skip to content

Commit 41e4c4f

Browse files
authored
Merge pull request #228 from angular-ui/buffer-first-last-length
Buffer first, last, length
2 parents 1f09429 + 7388784 commit 41e4c4f

14 files changed

+211
-7
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ Adapter object implements the following properties:
249249
* `topVisible`/`bottomVisible` - a read only reference to the item currently in the topmost/bottommost visible position.
250250
* `topVisibleElement`/`bottomVisibleElement` - a read only reference to the DOM element currently in the topmost/bottommost visible position.
251251
* `topVisibleScope`/`bottomVisibleScope` - a read only reference to the scope created for the item currently in the topmost/bottommost visible position.
252+
* `bufferLength` - a number of items currently in the ui-scroll buffer; equal to a number of DOM elements that are present in visible and invisible parts of the ui-scroll viewport.
253+
* `bufferFirst`/`bufferLast` - a read only reference to the first/last item currently in the ui-scroll buffer.
252254
* `disabled` - setting `disabled` to `true` disables scroller's scroll/resize events handlers. This can be useful if you have multiple scrollers within the same scrollViewport and you want to prevent some of them from responding to the events.
253255

254256
Adapter object implements the following methods
@@ -475,6 +477,10 @@ Pull Rerquest should include source code (./scr) changes, may include tests (./t
475477

476478
## Change log
477479

480+
### v1.7.5
481+
* Added bufferFirst, bufferLast, bufferLength read-only properties to the Adapter.
482+
* Fixed reload unsubscribe issue [226](https://github.com/angular-ui/ui-scroll/issues/226).
483+
478484
### v1.7.4
479485
* Fixed jqLite/jQuery confrontation.
480486

bower.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "angular-ui-scroll",
33
"description": "AngularJS infinite scrolling module",
4-
"version": "1.7.4",
4+
"version": "1.7.5",
55
"main": "./dist/ui-scroll.js",
66
"homepage": "https://github.com/angular-ui/ui-scroll.git",
77
"license": "MIT",

demo/bufferItems/bufferItems.html

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<!doctype html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Buffer first, last, length</title>
7+
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.1/angular.js"></script>
8+
<script src="../../dist/ui-scroll.js"></script>
9+
<script src="bufferItems.js"></script>
10+
<link rel="stylesheet" href="../css/style.css" type="text/css" />
11+
</head>
12+
13+
<body ng-app="application" ng-controller="mainController">
14+
15+
<div class="cont cont-global">
16+
17+
<a class="back" href="../index.html">browse other examples</a>
18+
19+
<h1 class="page-header page-header-exapmle">Buffer first, last, length</h1>
20+
21+
<div class="description">
22+
The ui-scroll Adapter has 3 read-only properties which provide information of current ui-scroll Buffer state.
23+
The buffer contains some visible items and some items that are out of visible part of the viewport.
24+
So with these properties we can get the topmost and the bottommost items that the ui-scroll is dealing with at the moment.
25+
At the template's layer it may look like
26+
27+
<div class="code">
28+
<pre>{{adapter.bufferFirst}<!---->}
29+
{{adapter.bufferLast}<!---->}
30+
{{adapter.bufferLength}<!---->}
31+
32+
&lt;li ui-scroll="item in datasource" adapter="adapter"&gt;{{item}<!---->}&lt;/li&gt;</pre>
33+
</div>
34+
</div>
35+
36+
<div class="info">
37+
<div class="info-item"><span class="info-item-label">First buffer</span> {{adapter.bufferFirst}}</div>
38+
<div class="info-item"><span class="info-item-label">Last buffer</span> {{adapter.bufferLast}}</div>
39+
<div class="info-item"><span class="info-item-label">Buffer length:</span> {{adapter.bufferLength}}</div>
40+
</div>
41+
42+
<div class="viewport" id="viewport-listScroller" ui-scroll-viewport>
43+
<ul>
44+
<li ui-scroll="item in datasource" adapter="adapter">{{item}}</li>
45+
</ul>
46+
</div>
47+
48+
</div>
49+
50+
</body>
51+
52+
</html>

demo/bufferItems/bufferItems.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
angular.module('application', ['ui.scroll'])
2+
.controller('mainController', [
3+
'$scope', '$log', '$timeout', function ($scope, console, $timeout) {
4+
5+
$scope.adapter = {};
6+
7+
$scope.datasource = {};
8+
9+
$scope.datasource.get = function (index, count, success) {
10+
$timeout(function () {
11+
var result = [];
12+
for (var i = index; i <= index + count - 1; i++) {
13+
result.push("item #" + i);
14+
}
15+
success(result);
16+
}, 0);
17+
};
18+
19+
}
20+
]);

demo/index.html

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ <h1 class="page-header">Scroller Examples</h1>
6464
Bottom visible (Adapter)
6565
</a>
6666
</li>
67+
<li>
68+
<a href="bufferItems/bufferItems.html">
69+
Buffer first, last, length
70+
</a>
71+
</li>
6772
<li>
6873
<a href="reload100/reload100.html">
6974
Reload datasource to specified index

dist/ui-scroll-grid.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ui-scroll.js

+54-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ui-scroll.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ui-scroll.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ui-scroll.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "angular-ui-scroll",
33
"description": "AngularJS infinite scrolling module",
4-
"version": "1.7.4",
4+
"version": "1.7.5",
55
"src": "./src/",
66
"public": "./dist/",
77
"main": "./dist/ui-scroll.js",

src/modules/adapter.js

+20
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ class Adapter {
6464
});
6565
}
6666

67+
// read-only immediately calculated public properties
68+
const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength'];
69+
for (let i = publicPropsImmediate.length - 1; i >= 0; i--) {
70+
Object.defineProperty(this.publicContext, publicPropsImmediate[i], {
71+
get: () => this[publicPropsImmediate[i]]
72+
});
73+
}
74+
6775
// non-read-only public property
6876
Object.defineProperty(this.publicContext, 'disabled', {
6977
get: () => this.disabled,
@@ -87,6 +95,18 @@ class Adapter {
8795
return !this.buffer.length;
8896
}
8997

98+
get bufferLength() {
99+
return this.buffer.getItems().length;
100+
}
101+
102+
get bufferFirst() {
103+
return this.buffer.getFirstItem();
104+
}
105+
106+
get bufferLast() {
107+
return this.buffer.getLastItem();
108+
}
109+
90110
append(newItems) {
91111
this.buffer.append(newItems);
92112
this.doAdjust();

src/modules/buffer.js

+20
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,26 @@ export default function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
144144
}
145145
});
146146
return Math.max(0, bottom - top);
147+
},
148+
149+
getItems() {
150+
return buffer.filter(item => item.op === 'none');
151+
},
152+
153+
getFirstItem() {
154+
const list = buffer.getItems();
155+
if (!list.length) {
156+
return null;
157+
}
158+
return list[0].item;
159+
},
160+
161+
getLastItem() {
162+
const list = buffer.getItems();
163+
if (!list.length) {
164+
return null;
165+
}
166+
return list[list.length - 1].item;
147167
}
148168

149169
});

test/AdapterTestsSpec.js

+28
Original file line numberDiff line numberDiff line change
@@ -1300,4 +1300,32 @@ describe('uiScroll', function () {
13001300

13011301
});
13021302

1303+
describe('adapter bufferFirst, bufferLast, bufferLength', function () {
1304+
var scrollSettings = { datasource: 'myMultipageDatasource', adapter: 'adapter', viewportHeight: 80, itemHeight: 20 };
1305+
1306+
it('without scroll', function () {
1307+
runTest(scrollSettings,
1308+
function (viewport, scope) {
1309+
expect(scope.adapter.bufferFirst).toBe('item1');
1310+
expect(scope.adapter.bufferLast).toBe('item10');
1311+
expect(scope.adapter.bufferLength).toBe(10);
1312+
}
1313+
);
1314+
});
1315+
1316+
it('scroll to the bottom', function () {
1317+
runTest(scrollSettings,
1318+
function (viewport, scope) {
1319+
viewport.scrollTop(10000);
1320+
viewport.trigger('scroll');
1321+
1322+
expect(scope.adapter.bufferFirst).toBe('item5');
1323+
expect(scope.adapter.bufferLast).toBe('item20');
1324+
expect(scope.adapter.bufferLength).toBe(16);
1325+
}
1326+
);
1327+
});
1328+
1329+
});
1330+
13031331
});

0 commit comments

Comments
 (0)