Skip to content

Buffer first, last, length #228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ Adapter object implements the following properties:
* `topVisible`/`bottomVisible` - a read only reference to the item currently in the topmost/bottommost visible position.
* `topVisibleElement`/`bottomVisibleElement` - a read only reference to the DOM element currently in the topmost/bottommost visible position.
* `topVisibleScope`/`bottomVisibleScope` - a read only reference to the scope created for the item currently in the topmost/bottommost visible position.
* `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.
* `bufferFirst`/`bufferLast` - a read only reference to the first/last item currently in the ui-scroll buffer.
* `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.

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

## Change log

### v1.7.5
* Added bufferFirst, bufferLast, bufferLength read-only properties to the Adapter.
* Fixed reload unsubscribe issue [226](https://github.com/angular-ui/ui-scroll/issues/226).

### v1.7.4
* Fixed jqLite/jQuery confrontation.

Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "angular-ui-scroll",
"description": "AngularJS infinite scrolling module",
"version": "1.7.4",
"version": "1.7.5",
"main": "./dist/ui-scroll.js",
"homepage": "https://github.com/angular-ui/ui-scroll.git",
"license": "MIT",
Expand Down
52 changes: 52 additions & 0 deletions demo/bufferItems/bufferItems.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>Buffer first, last, length</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.1/angular.js"></script>
<script src="../../dist/ui-scroll.js"></script>
<script src="bufferItems.js"></script>
<link rel="stylesheet" href="../css/style.css" type="text/css" />
</head>

<body ng-app="application" ng-controller="mainController">

<div class="cont cont-global">

<a class="back" href="../index.html">browse other examples</a>

<h1 class="page-header page-header-exapmle">Buffer first, last, length</h1>

<div class="description">
The ui-scroll Adapter has 3 read-only properties which provide information of current ui-scroll Buffer state.
The buffer contains some visible items and some items that are out of visible part of the viewport.
So with these properties we can get the topmost and the bottommost items that the ui-scroll is dealing with at the moment.
At the template's layer it may look like

<div class="code">
<pre>{{adapter.bufferFirst}<!---->}
{{adapter.bufferLast}<!---->}
{{adapter.bufferLength}<!---->}

&lt;li ui-scroll="item in datasource" adapter="adapter"&gt;{{item}<!---->}&lt;/li&gt;</pre>
</div>
</div>

<div class="info">
<div class="info-item"><span class="info-item-label">First buffer</span> {{adapter.bufferFirst}}</div>
<div class="info-item"><span class="info-item-label">Last buffer</span> {{adapter.bufferLast}}</div>
<div class="info-item"><span class="info-item-label">Buffer length:</span> {{adapter.bufferLength}}</div>
</div>

<div class="viewport" id="viewport-listScroller" ui-scroll-viewport>
<ul>
<li ui-scroll="item in datasource" adapter="adapter">{{item}}</li>
</ul>
</div>

</div>

</body>

</html>
20 changes: 20 additions & 0 deletions demo/bufferItems/bufferItems.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
angular.module('application', ['ui.scroll'])
.controller('mainController', [
'$scope', '$log', '$timeout', function ($scope, console, $timeout) {

$scope.adapter = {};

$scope.datasource = {};

$scope.datasource.get = function (index, count, success) {
$timeout(function () {
var result = [];
for (var i = index; i <= index + count - 1; i++) {
result.push("item #" + i);
}
success(result);
}, 0);
};

}
]);
5 changes: 5 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ <h1 class="page-header">Scroller Examples</h1>
Bottom visible (Adapter)
</a>
</li>
<li>
<a href="bufferItems/bufferItems.html">
Buffer first, last, length
</a>
</li>
<li>
<a href="reload100/reload100.html">
Reload datasource to specified index
Expand Down
2 changes: 1 addition & 1 deletion dist/ui-scroll-grid.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 54 additions & 1 deletion dist/ui-scroll.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/ui-scroll.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ui-scroll.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ui-scroll.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "angular-ui-scroll",
"description": "AngularJS infinite scrolling module",
"version": "1.7.4",
"version": "1.7.5",
"src": "./src/",
"public": "./dist/",
"main": "./dist/ui-scroll.js",
Expand Down
20 changes: 20 additions & 0 deletions src/modules/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ class Adapter {
});
}

// read-only immediately calculated public properties
const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength'];
for (let i = publicPropsImmediate.length - 1; i >= 0; i--) {
Object.defineProperty(this.publicContext, publicPropsImmediate[i], {
get: () => this[publicPropsImmediate[i]]
});
}

// non-read-only public property
Object.defineProperty(this.publicContext, 'disabled', {
get: () => this.disabled,
Expand All @@ -87,6 +95,18 @@ class Adapter {
return !this.buffer.length;
}

get bufferLength() {
return this.buffer.getItems().length;
}

get bufferFirst() {
return this.buffer.getFirstItem();
}

get bufferLast() {
return this.buffer.getLastItem();
}

append(newItems) {
this.buffer.append(newItems);
this.doAdjust();
Expand Down
20 changes: 20 additions & 0 deletions src/modules/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,26 @@ export default function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
}
});
return Math.max(0, bottom - top);
},

getItems() {
return buffer.filter(item => item.op === 'none');
},

getFirstItem() {
const list = buffer.getItems();
if (!list.length) {
return null;
}
return list[0].item;
},

getLastItem() {
const list = buffer.getItems();
if (!list.length) {
return null;
}
return list[list.length - 1].item;
}

});
Expand Down
28 changes: 28 additions & 0 deletions test/AdapterTestsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1300,4 +1300,32 @@ describe('uiScroll', function () {

});

describe('adapter bufferFirst, bufferLast, bufferLength', function () {
var scrollSettings = { datasource: 'myMultipageDatasource', adapter: 'adapter', viewportHeight: 80, itemHeight: 20 };

it('without scroll', function () {
runTest(scrollSettings,
function (viewport, scope) {
expect(scope.adapter.bufferFirst).toBe('item1');
expect(scope.adapter.bufferLast).toBe('item10');
expect(scope.adapter.bufferLength).toBe(10);
}
);
});

it('scroll to the bottom', function () {
runTest(scrollSettings,
function (viewport, scope) {
viewport.scrollTop(10000);
viewport.trigger('scroll');

expect(scope.adapter.bufferFirst).toBe('item5');
expect(scope.adapter.bufferLast).toBe('item20');
expect(scope.adapter.bufferLength).toBe(16);
}
);
});

});

});