Skip to content

Commit f1a3516

Browse files
authored
Merge pull request #188 from angular-ui/paddings-cache
Paddings cache
2 parents 990e0bf + d1fdd30 commit f1a3516

27 files changed

+1209
-416
lines changed

Gruntfile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ module.exports = function (grunt) {
4444
},
4545
karma: {
4646
options: {
47-
configFile: './test/karma.conf.js',
47+
configFile: './test/config/karma.conf.js',
4848
runnerPort: 9100
4949
},
5050
default: {},
5151
compressed: {
5252
options: {
53-
files: require('./test/karma.conf.files.js').compressedFiles,
53+
files: require('./test/config/karma.conf.files.js').compressedFiles,
5454
port: 9876,
5555
autoWatch: false,
5656
keepalive: false,

demo/adapterSync/adapterSync.html

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<title>Adapter sync</title>
66
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
77
<script src="../../dist/ui-scroll.js"></script>
8+
<script src="server.js"></script>
89
<script src="adapterSync.js"></script>
910
<link rel="stylesheet" href="../css/style.css" type="text/css"/>
1011
<style>
@@ -19,6 +20,12 @@
1920
.viewport2 .uid {
2021
font-size: x-small;
2122
}
23+
.some {
24+
margin-top: 5px;
25+
}
26+
.some input {
27+
width: 50px;
28+
}
2229
</style>
2330
</head>
2431
<body ng-controller="mainController as mainCtrl" ng-app="application">
@@ -31,40 +38,55 @@ <h1 class="page-header page-header-exapmle">Adapter: append, prepend and remove
3138

3239
<div class="description">
3340
<p>
34-
In this demo we are playing with adding/removing items via adapter append, prepend and applyUpdates methods.
35-
All changes made on the front end have to be synced and stored on the back end.
36-
For this purpose a special Server factory was introduced to emulate the remote.
41+
This demo had been created to show Adapter 'append', 'prepend' and 'applyUpdates' methods in action.
42+
The main point here is that all changes made on the front end have to be synced and stored on the back end.
43+
For this purpose a special Server module was introduced to emulate the remote server.
3744
The following public methods are implemented by this Server factory:<br/>
3845
<ul>
3946
<li>
40-
<em>appendItem(params)</em> to add one new item (based on params) to the end of the remote data set,
47+
<b>request(index, count)</b> just to fetch a bunch of items for the viewport;
4148
</li>
4249
<li>
43-
<em>prependItem(params)</em> to add one new item (based on params) to the beginning of the remote data
44-
set,
50+
<b>appendItem(params)</b> to add one new item (based on params) to the end of the remote data set;
4551
</li>
4652
<li>
47-
<em>removeItemById(id)</em> remove one item (based on id) form the remote data set,
48-
set,
53+
<b>prependItem(params)</b> to add one new item (based on params) to the beginning of the remote data;
4954
</li>
5055
<li>
51-
<em>request(index, count)</em> just to fetch a bunch of items for the viewport.
56+
<b>insertAfterIndex(index, params)</b> to add one new item (based on params) after the item with given index;
57+
</li>
58+
<li>
59+
<b>removeFirst()</b> remove first item;
60+
</li>
61+
<li>
62+
<b>removeLast()</b> remove last item;
63+
</li>
64+
<li>
65+
<b>removeItemById(id)</b> remove one item (based on id).
5266
</li>
5367
</ul>
54-
The initial data set consists of 40 items and can be extended unlimitedly.
68+
The initial data set consists of 40 items and can be extended/reduced unlimitedly.
5569
</p>
56-
<p> Follow the sources of the demo! The implementation of the Server factory is not trivial, it is based on
57-
indexes variations. Also you may see that new items would not be appended (<em>adapter.append()</em>) to the
58-
viewport immediately if the EOF (end of file) is not reached. The same is true for prepend operation
59-
(<em>adapter.prepend()</em>): BOF (begin of file) must be reached, otherwise your new item will be rendered
60-
only after scrolling to the very top... This is important to build proper UI.
70+
<p>
71+
The implementation of the Server factory is not trivial, it is based on indicies variations.
72+
Also you may see that new items would not be appended (via 'Append one item' or
73+
'Insert some after index' buttons) to the viewport immediately if the EOF (end of file) is not reached.
74+
The same is true for prepend operation ('Prepend one item'): BOF (begin of file) must be reached,
75+
otherwise your new item will be rendered only after scrolling to the very top...
76+
This is important to build proper UI.
6177
</p>
6278
</div>
6379

6480
<div class="actions">
6581
<button ng-click="mainCtrl.prepend()">Prepend one item</button>
6682
<button ng-click="mainCtrl.append()">Append one item</button>
6783
<!--button ng-click="mainCtrl.removeAll()">Clear the viewport</button-->
84+
<button ng-click="mainCtrl.removeFirst()">Remove first</button>
85+
<button ng-click="mainCtrl.removeLast()">Remove last</button>
86+
<div class="some">
87+
<button ng-click="mainCtrl.insertSome(ctrl.indexToInsert)">Insert some after index</button>
88+
<input ng-model="ctrl.indexToInsert">
89+
</div>
6890
</div>
6991

7092
<br/>

demo/adapterSync/adapterSync.js

Lines changed: 58 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,4 @@
1-
var app = angular.module('application', ['ui.scroll']);
2-
3-
app.factory('Server', [
4-
'$timeout', '$q', function ($timeout, $q) {
5-
6-
var ServerFactory = {
7-
8-
firstIndex: 1,
9-
10-
lastIndex: 40,
11-
12-
delay: 100,
13-
14-
data: [],
15-
16-
absIndex: 1,
17-
18-
generateId: function () {
19-
var d = '-';
20-
function S4() {
21-
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
22-
}
23-
return (S4() + S4() + d + S4() + d + S4() + d + S4() + d + S4() + S4() + S4());
24-
},
25-
26-
generateItem: function (index) {
27-
return {
28-
index: index,
29-
id: this.generateId(),
30-
content: 'Item #' + this.absIndex++
31-
}
32-
},
33-
34-
init: function () {
35-
for (var i = this.firstIndex; i <= this.lastIndex; i++) {
36-
this.data.push(this.generateItem(i));
37-
}
38-
},
39-
40-
getItem: function (index) {
41-
for (var i = this.data.length - 1; i >= 0; i--) {
42-
if (this.data[i].index === index) {
43-
return this.data[i];
44-
}
45-
}
46-
},
47-
48-
returnDeferredResult: function (result) {
49-
var deferred = $q.defer();
50-
$timeout(function () {
51-
deferred.resolve(result);
52-
}, this.delay);
53-
return deferred.promise;
54-
},
55-
56-
request: function (index, count) {
57-
var start = index;
58-
var end = index + count - 1;
59-
var item, result = {
60-
items: []
61-
};
62-
if (start <= end) {
63-
for (var i = start; i <= end; i++) {
64-
if (item = this.getItem(i)) {
65-
result.items.push(item);
66-
}
67-
}
68-
}
69-
return this.returnDeferredResult(result);
70-
},
71-
72-
prependItem: function (params) {
73-
var newItem = this.generateItem(--this.firstIndex);
74-
newItem.content += params;
75-
this.data.unshift(newItem);
76-
return this.returnDeferredResult(newItem);
77-
},
78-
79-
appendItem: function (params) {
80-
var newItem = this.generateItem(++this.lastIndex);
81-
newItem.content += params;
82-
this.data.push(newItem);
83-
return this.returnDeferredResult(newItem);
84-
},
85-
86-
removeItemById: function (itemId) {
87-
var length = this.data.length;
88-
for (var i = 0; i < length; i++) {
89-
if (this.data[i].id === itemId) {
90-
this.data.splice(i, 1);
91-
this.setIndicies();
92-
return this.returnDeferredResult(true);
93-
}
94-
}
95-
return this.returnDeferredResult(false);
96-
},
97-
98-
setIndicies: function() {
99-
if(!this.data.length) {
100-
this.firstIndex = 1;
101-
this.lastIndex = 1;
102-
return;
103-
}
104-
this.firstIndex = this.data[0].index;
105-
this.lastIndex = this.data[0].index;
106-
for (var i = this.data.length - 1; i >= 0; i--) {
107-
if(this.data[i].index > this.lastIndex) {
108-
this.lastIndex = this.data[i].index;
109-
}
110-
if(this.data[i].index < this.firstIndex) {
111-
this.firstIndex = this.data[i].index;
112-
}
113-
}
114-
}
115-
};
116-
117-
ServerFactory.init();
118-
119-
return ServerFactory;
120-
121-
}
122-
]);
123-
1+
var app = angular.module('application', ['ui.scroll', 'server']);
1242

1253
app.controller('mainController', [
1264
'$scope', 'Server', function ($scope, Server) {
@@ -171,7 +49,7 @@ app.controller('mainController', [
17149

17250
ctrl.remove = function (itemRemove) {
17351
Server.removeItemById(itemRemove.id).then(function (result) {
174-
if (result) {
52+
if (result !== false) {
17553
ctrl.adapter.applyUpdates(function (item) {
17654
if (item.id === itemRemove.id) {
17755
return [];
@@ -181,5 +59,61 @@ app.controller('mainController', [
18159
});
18260
};
18361

62+
ctrl.removeFirst = function () {
63+
Server.removeFirst().then(function (indexRemoved) {
64+
if (indexRemoved !== false) {
65+
ctrl.adapter.applyUpdates(indexRemoved, []);
66+
}
67+
});
68+
};
69+
70+
ctrl.removeLast = function () {
71+
Server.removeLast().then(function (indexRemoved) {
72+
if (indexRemoved !== false) {
73+
ctrl.adapter.applyUpdates(indexRemoved, []);
74+
}
75+
});
76+
};
77+
78+
ctrl.insertSome = function (indexToInsert) {
79+
indexToInsert = parseInt(indexToInsert, 10);
80+
var promises = [
81+
Server.insertAfterIndex(indexToInsert, ' *** (1)'),
82+
Server.insertAfterIndex(indexToInsert + 1, ' *** (2)'),
83+
Server.insertAfterIndex(indexToInsert + 2, ' *** (3)')
84+
];
85+
Promise.all(promises).then(function (result) {
86+
if (result && result.length) {
87+
// need to protect from null
88+
var _result = [];
89+
for(var i = 0; i < result.length; i++) {
90+
if(result[i]) {
91+
_result.push(result[i]);
92+
}
93+
}
94+
if(_result.length) {
95+
var item = getItemByIndex(indexToInsert);
96+
if(item) {
97+
_result.unshift(item);
98+
}
99+
ctrl.adapter.applyUpdates(indexToInsert, _result);
100+
}
101+
}
102+
});
103+
};
104+
105+
function getItemByIndex(index) {
106+
var foundItem = null;
107+
// use Adapter.applyUpdates to get indexed item from Buffer
108+
ctrl.adapter.applyUpdates(function (item) {
109+
if (item.index === index) {
110+
foundItem = item;
111+
}
112+
});
113+
return foundItem;
114+
}
115+
116+
ctrl.datasource.minIndex = Server.firstIndex;
117+
ctrl.datasource.maxIndex = Server.lastIndex;
184118
}
185119
]);

0 commit comments

Comments
 (0)