Skip to content

Commit 4f38b8f

Browse files
committed
Adapter sync demo: append, prepend and remove (via applyUpdates)
1 parent 1482b77 commit 4f38b8f

File tree

7 files changed

+259
-5
lines changed

7 files changed

+259
-5
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ exactly `count` elements unless it hit eof/bof.
211211
Values of the properties can be assigned programmatically. If the range of the index values is known in advance, assigning them programmatically would improve the usability of the scrollBar.
212212

213213

214-
###Adapter
214+
### Adapter
215215

216216
The adapter object is an internal object created for every instance of the scroller. Properties and methods of the adapter can be used to manipulate and assess the scroller the adapter was created for.
217217

demo/adapterSync/adapterSync.html

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Adapter sync</title>
6+
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
7+
<script src="../../dist/ui-scroll.js"></script>
8+
<script src="adapterSync.js"></script>
9+
<link rel="stylesheet" href="../css/style.css" type="text/css"/>
10+
<style>
11+
.remove {
12+
float: right;
13+
margin-right: 15px;
14+
cursor: pointer;
15+
}
16+
.remove:hover {
17+
color: #a00;
18+
}
19+
</style>
20+
</head>
21+
<body ng-controller="mainController" ng-app="application">
22+
23+
<div class="cont cont-global">
24+
25+
<a class="back" href="../index.html">browse other examples</a>
26+
27+
<h1 class="page-header page-header-exapmle">Adapter: append, prepend and remove sync</h1>
28+
29+
<div class="description">
30+
<p>
31+
In this demo we are playing with adding/removing items via adapter append, prepend and applyUpdates methods.
32+
All changes have to be synced and stored on the back end.
33+
For this purpose a special Server factory was introduced to emulate the remote.
34+
Some public methods are implemented by this Server factory:<br/>
35+
<ul>
36+
<li>
37+
<em>appendItem(params)</em> to add one new item (based on params) to the end of the remote data set,
38+
</li>
39+
<li>
40+
<em>prependItem(params)</em> to add one new item (based on params) in the beginning of the remote data
41+
set,
42+
</li>
43+
<li>
44+
<em>removeItemById(id)</em> remove one item (based on id) form the remote data set,
45+
set,
46+
</li>
47+
<li>
48+
<em>request(index, count)</em> just to fetch a bunch of items for the viewport.
49+
</li>
50+
</ul>
51+
The initial data set consists of 90 items and can be extended unlimitedly.
52+
</p>
53+
<p> Follow the sources of the demo! The implementation of the Server factory is not so trivial, it is based on
54+
indexes variations. Also you may see that new items would not be appended (<em>adapter.append()</em>) to the
55+
viewport immediately if the EOF (end of file) is not reached. The same is true for prepend operation
56+
(<em>adapter.prepend()</em>): BOF (begin of file) must be reached, otherwise your new item will be rendered
57+
only after scrolling to the very top... This is important to build proper UI.
58+
</p>
59+
</div>
60+
61+
<div class="actions">
62+
<button ng-click="prepend()">Prepend one item</button>
63+
<button ng-click="append()">Append one item</button>
64+
<!--button ng-click="removeAll()">Clear the viewport</button-->
65+
</div>
66+
67+
<br/>
68+
69+
<ul class="viewport2" ui-scroll-viewport>
70+
<li ui-scroll="item in datasource" adapter="adapter">
71+
<div>
72+
<span>{{item.content}} <span class="uid">({{item.id}})</span></span>
73+
<span class="remove" ng-click="remove(item)">[x]</span>
74+
</div>
75+
</li>
76+
</ul>
77+
78+
</div>
79+
</body>
80+
</html>

demo/adapterSync/adapterSync.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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: 90,
11+
12+
delay: 100,
13+
14+
data: [],
15+
16+
generateId: function () {
17+
var d = '-';
18+
function S4() {
19+
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
20+
}
21+
return (S4() + S4() + d + S4() + d + S4() + d + S4() + d + S4() + S4() + S4());
22+
},
23+
24+
generateItem: function (number) {
25+
return {
26+
index: number,
27+
id: this.generateId(),
28+
content: 'Item #' + number
29+
}
30+
},
31+
32+
init: function () {
33+
for (var i = this.firstIndex; i <= this.lastIndex; i++) {
34+
this.data.push(this.generateItem(i));
35+
}
36+
},
37+
38+
getItem: function (index) {
39+
for (var i = this.data.length - 1; i >= 0; i--) {
40+
if (this.data[i].index === index) {
41+
return this.data[i];
42+
}
43+
}
44+
},
45+
46+
returnDeferredResult: function (result) {
47+
var deferred = $q.defer();
48+
$timeout(function () {
49+
deferred.resolve(result);
50+
}, this.delay);
51+
return deferred.promise;
52+
},
53+
54+
request: function (index, count) {
55+
var start = index;
56+
var end = index + count - 1;
57+
var item, result = {
58+
items: []
59+
};
60+
if (start <= end) {
61+
for (var i = start; i <= end; i++) {
62+
if (item = this.getItem(i)) {
63+
result.items.push(item);
64+
}
65+
}
66+
}
67+
return this.returnDeferredResult(result);
68+
},
69+
70+
prependItem: function (params) {
71+
var prependedDataIndex = this.firstIndex-- - 1;
72+
var newItem = this.generateItem(prependedDataIndex);
73+
newItem.content += params;
74+
this.data.unshift(newItem);
75+
return this.returnDeferredResult(newItem);
76+
},
77+
78+
appendItem: function (params) {
79+
var appendedDataIndex = this.lastIndex++ + 1;
80+
var newItem = this.generateItem(appendedDataIndex);
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+
for (var j = i; j < length - 1; j++) {
92+
this.data[j].index--;
93+
}
94+
return this.returnDeferredResult(true);
95+
}
96+
}
97+
return this.returnDeferredResult(false);
98+
}
99+
};
100+
101+
ServerFactory.init();
102+
103+
return ServerFactory;
104+
105+
}
106+
]);
107+
108+
109+
app.controller('mainController', [
110+
'$scope', 'Server', function ($scope, Server) {
111+
112+
$scope.datasource = {
113+
get: function (index, count, success) {
114+
console.log('request by index = ' + index + ', count = ' + count);
115+
Server.request(index, count).then(function (result) {
116+
if (result.items.length) {
117+
console.log('resolved ' + result.items.length + ' items');
118+
}
119+
success(result.items);
120+
});
121+
}
122+
};
123+
124+
$scope.prepend = function () {
125+
Server.prependItem(' ***').then(function (newItem) {
126+
if ($scope.adapter.isBOF()) {
127+
$scope.adapter.prepend([newItem]);
128+
}
129+
});
130+
};
131+
132+
$scope.append = function () {
133+
Server.appendItem(' ***').then(function (newItem) {
134+
if ($scope.adapter.isEOF()) {
135+
$scope.adapter.append([newItem]);
136+
}
137+
});
138+
};
139+
140+
/*$scope.removeAll = function () {
141+
$scope.adapter.applyUpdates(function (item) {
142+
if (item.id) {
143+
return [];
144+
}
145+
});
146+
};*/
147+
148+
$scope.remove = function (itemRemove) {
149+
Server.removeItemById(itemRemove.id).then(function (result) {
150+
if (result) {
151+
$scope.adapter.applyUpdates(function (item) {
152+
if (item.id === itemRemove.id) {
153+
return [];
154+
}
155+
});
156+
}
157+
});
158+
};
159+
160+
}
161+
]);

demo/append/append.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

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

17-
<h1 class="page-header page-header-exapmle">Append and prepend demo</h1>
17+
<h1 class="page-header page-header-exapmle">Adapter: append and prepend sync</h1>
1818

1919
<div class="description">
2020
<p>

demo/css/style.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,11 @@
173173
height: 300px;
174174
list-style: none;
175175
padding: 0;
176-
width: 300px;
176+
width: 400px;
177+
}
178+
.viewport2 .uid {
179+
font-size: small;
180+
color: #aaa;
177181
}
178182
.viewport {
179183
margin-top: 15px;

demo/css/style.less

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,11 @@
237237
height: 300px;
238238
list-style: none;
239239
padding: 0;
240-
width: 300px;
240+
width: 400px;
241+
.uid {
242+
font-size: small;
243+
color: #aaa;
244+
}
241245
}
242246

243247
.viewport {

demo/index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,12 @@ <h1 class="page-header">Scroller Examples</h1>
136136
</li>
137137
<li>
138138
<a href="append/append.html">
139-
Append and prepend sync demo
139+
Adapter: append and prepend sync demo
140+
</a>
141+
</li>
142+
<li>
143+
<a href="adapterSync/adapterSync.html">
144+
Adapter: append, prepend and remove sync demo
140145
</a>
141146
</li>
142147
<li>

0 commit comments

Comments
 (0)