Skip to content

Commit daf14fa

Browse files
committed
adapter sync demo refactoring
1 parent 6238309 commit daf14fa

File tree

3 files changed

+239
-160
lines changed

3 files changed

+239
-160
lines changed

demo/adapterSync/adapterSync.html

Lines changed: 35 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,33 +38,42 @@ <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

@@ -67,6 +83,10 @@ <h1 class="page-header page-header-exapmle">Adapter: append, prepend and remove
6783
<!--button ng-click="mainCtrl.removeAll()">Clear the viewport</button-->
6884
<button ng-click="mainCtrl.removeFirst()">Remove first</button>
6985
<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>
7090
</div>
7191

7292
<br/>

demo/adapterSync/adapterSync.js

Lines changed: 42 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +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-
removeFirst: function () {
87-
var firstItem = this.data.find(i => i.index === this.firstIndex);
88-
if(!firstItem) {
89-
return $q.reject();
90-
}
91-
return this.removeItemById(firstItem.id);
92-
},
93-
94-
removeLast: function () {
95-
var lastItem = this.data.find(i => i.index === this.lastIndex);
96-
if(!lastItem) {
97-
return $q.reject();
98-
}
99-
return this.removeItemById(lastItem.id);
100-
},
101-
102-
removeItemById: function (itemId) {
103-
var length = this.data.length;
104-
for (var i = 0; i < length; i++) {
105-
if (this.data[i].id === itemId) {
106-
var indexRemoved = this.data[i].index;
107-
if(indexRemoved > this.firstIndex) {
108-
for (var j = i; j < length; j++) {
109-
this.data[j].index--;
110-
}
111-
}
112-
this.data.splice(i, 1);
113-
this.setIndicies();
114-
return this.returnDeferredResult(indexRemoved);
115-
}
116-
}
117-
return this.returnDeferredResult(false);
118-
},
119-
120-
setIndicies: function() {
121-
if(!this.data.length) {
122-
this.firstIndex = 1;
123-
this.lastIndex = 1;
124-
return;
125-
}
126-
this.firstIndex = this.data[0].index;
127-
this.lastIndex = this.data[0].index;
128-
for (var i = this.data.length - 1; i >= 0; i--) {
129-
if(this.data[i].index > this.lastIndex) {
130-
this.lastIndex = this.data[i].index;
131-
}
132-
if(this.data[i].index < this.firstIndex) {
133-
this.firstIndex = this.data[i].index;
134-
}
135-
}
136-
}
137-
};
138-
139-
ServerFactory.init();
140-
141-
return ServerFactory;
142-
143-
}
144-
]);
145-
1+
var app = angular.module('application', ['ui.scroll', 'server']);
1462

1473
app.controller('mainController', [
1484
'$scope', 'Server', function ($scope, Server) {
@@ -218,5 +74,46 @@ app.controller('mainController', [
21874
}
21975
});
22076
};
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;
221118
}
222119
]);

0 commit comments

Comments
 (0)