|
1 | | -# Angular Live Set: Example |
2 | | - |
3 | | -**⚠️ This LoopBack 3 example project is no longer maintained. Please refer to [LoopBack 4 Examples](https://loopback.io/doc/en/lb4/Examples.html) instead. ⚠️** |
4 | | - |
5 | | -## What is LiveSet? |
6 | | - |
7 | | -[LiveSet](https://github.com/strongloop/angular-live-set) is an angular module that allows you to display an always up to date collection of objects. |
8 | | - |
9 | | - |
10 | | - |
11 | | -## Lets see the code! |
12 | | - |
13 | | -**Favorite Colors** |
14 | | - |
15 | | -This is a snippet from the [colors example](https://github.com/strongloop/loopback-example-angular-live-set/blob/update-readme/client/modules/color/color-list.controller.js) that demonstrates a basic |
16 | | -`LiveSet`. |
17 | | - |
18 | | -```js |
19 | | -var src = new EventSource('/api/colors/change-stream'); |
20 | | -var changes = createChangeStream(src); |
21 | | -var set; |
22 | | - |
23 | | -Color.find().$promise.then(function(results) { |
24 | | - set = new LiveSet(results, changes); |
25 | | - $scope.colors = set.toLiveArray(); |
26 | | -}); |
27 | | -``` |
28 | | - |
29 | | -**Live Drawing** |
30 | | - |
31 | | -The drawing example creates a `LiveSet` in a similar way. The rest of the controller is fairly simple and similar to the snippet above. |
32 | | - |
33 | | -The draw method uses a service provided by the [loopback-angular-sdk](http://loopback.io/doc/en/lb3/AngularJS-JavaScript-SDK.html) to create additional points in the drawing. This data is streamed to other browser clients. |
34 | | - |
35 | | -```js |
36 | | -$scope.draw = function(e) { |
37 | | - if($scope.drawing) { |
38 | | - Circle.create({ |
39 | | - x: e.offsetX, |
40 | | - y: e.offsetY, |
41 | | - r: Math.floor(10 * Math.random()) |
42 | | - }); |
43 | | - } |
44 | | -} |
45 | | -``` |
46 | | - |
47 | | -**Streaming Chart** |
48 | | - |
49 | | -The streaming chart does not use the `LiveSet` class at all. It demonstrates how to stream data from the server to a client. |
50 | | - |
51 | | -```js |
52 | | -var src = new EventSource('/api/process/memory'); |
53 | | -var changes = createChangeStream(src); |
54 | | - |
55 | | -changes.on('data', function(update) { |
56 | | - // add the new data to the chart |
57 | | -}); |
58 | | -``` |
59 | | - |
60 | | -See the [entire chart example code](https://github.com/strongloop/loopback-example-angular-live-set/blob/update-readme/client/modules/chart). |
61 | | - |
62 | | -## Creating the Colors Example |
63 | | - |
64 | | -**Step 1: Dependencies** |
65 | | - |
66 | | -You will need the following node modules: |
67 | | - |
68 | | - - loopback |
69 | | - - your favorite gulp or grunt plugins |
70 | | - - gulp-loopback-angular (or the grunt version) |
71 | | - |
72 | | -Also the following bower packages: |
73 | | - |
74 | | - - angular |
75 | | - - angular-resource |
76 | | - - angular-live-set |
77 | | - |
78 | | -This tutorial assumes you are aware of setting up a basic angular application and |
79 | | -its dependencies. You can use gulp or grunt or nothing at all. |
80 | | - |
81 | | -Once you have your angular application running in a browser including the dependencies |
82 | | -mentioned above, you can start using the `lbServices` and `LiveSet` modules to |
83 | | -build the application. |
84 | | - |
85 | | -**Step 2: The API** |
86 | | - |
87 | | -This example was created first by running `lb app`. If you are unfamiliar |
88 | | -with creating LoopBack apps read more about it here. |
89 | | - |
90 | | -Once you have the LoopBack API scaffolded, you can add a model. We'll start with |
91 | | -a simple `Color` model just to get some data on the page. |
92 | | - |
93 | | -``` |
94 | | -lb model |
95 | | -``` |
96 | | - |
97 | | -Create the property `val`. Select `string` for the type. Add another property |
98 | | -named `votes`. This should be a `number`. |
99 | | - |
100 | | -Generate your `lb-services.js` angular module using the **loopback-angular-sdk**. |
101 | | -This will give you access to the `Color` resource in your angular app. Make sure |
102 | | -you include the script tag and register the module as an angular dependency for |
103 | | -the `lbServices` module (generated by loopback-angular-sdk). You also must include |
104 | | -the source for the `ngResource` module (which you should have installed as part |
105 | | -of step 1). |
106 | | - |
107 | | -**Step 3: The Controller** |
108 | | - |
109 | | -Now that you have a `Color` model API and the **angular-live-set** module |
110 | | -available from your angular app, you can create a simple controller for interacting |
111 | | -with the `Color` data. |
112 | | - |
113 | | -Start with a simple template that renders an array of color objects. I'll assume |
114 | | -you know how to do this. The template should look a bit like this: |
115 | | - |
116 | | -```html |
117 | | -<div ng-controller="ColorCtrl"> |
118 | | - <div ng-repeat="color in colors"> |
119 | | - <button |
120 | | - ng-click="upvote(color.id)" |
121 | | - style="background: {{ color.val }}">{{ color.votes }}</button> |
122 | | - </div> |
123 | | -</div> |
124 | | -``` |
125 | | - |
126 | | -Within our controller we need to create a `LiveSet` of colors as well as |
127 | | -implement the `createColor()` and `upvote()` methods. It should look something |
128 | | -like this. |
129 | | - |
130 | | -```js |
131 | | -function ColorCtrl($scope, createChangeStream, LiveSet, Color) { |
132 | | - $scope.upvote = function(id) { |
133 | | - Color.upvote({id: id}); |
134 | | - } |
135 | | - |
136 | | - $scope.newColor = 'red'; |
137 | | - |
138 | | - $scope.createColor = function() { |
139 | | - Color.create({val: $scope.newColor, votes: 0}); |
140 | | - } |
141 | | -} |
142 | | -``` |
143 | | - |
144 | | -And in our model source code we need to add the upvote method: |
145 | | - |
146 | | -```js |
147 | | -Color.upvote = function(id, cb) { |
148 | | - Color.findById(id, function(err, color) { |
149 | | - if(err) return cb(err); |
150 | | - color.votes += 1; |
151 | | - color.save(cb); |
152 | | - }); |
153 | | -}; |
154 | | - |
155 | | -Color.remoteMethod('upvote', { |
156 | | - isStatic: true, |
157 | | - accepts: {arg: 'id', type: 'number'} |
158 | | -}); |
159 | | -``` |
160 | | - |
161 | | -**Step 4: The LiveSet** |
162 | | - |
163 | | -The last step is to add the actual live set. |
164 | | - |
165 | | -```js |
166 | | -// this should be added to our controller |
167 | | -var changeStreamUrl = '/api/colors/subscription?_format=event-source'; |
168 | | -var src = new EventSource(changeStreamUrl); |
169 | | -var changes = createChangeStream(src); |
170 | | -var set; |
171 | | - |
172 | | -Color.find().$promise.then(function(colors) { |
173 | | - set = new LiveSet(colors, changes); |
174 | | - $scope.colors = set.toLiveArray(); |
175 | | -}); |
176 | | -``` |
177 | | - |
178 | | -The code above creates a `LiveSet` from a `ChangeStream`. The `LiveSet` is a |
179 | | -read only collection of data. The items in the set will be updated as changes |
180 | | -are written to the `ChangeStream`. |
181 | | - |
182 | | -Since the change stream was created with an `EventSource` the changes will be |
183 | | -written from the server **as they are made**. This will keep the data in the |
184 | | -`LiveSet` up to date. |
185 | | - |
186 | | -Also, the `LiveSet` will make sure that changes are applied to the `$scope`. |
187 | | -This means for many use cases, you can create a `LiveSet` as a view of the data |
188 | | -and use the model api (eg. `Color`) to modify the data. Once the change has been |
189 | | -made on the server, the change will be made to your `LiveSet`. |
190 | | - |
191 | | -**Compatibility** |
192 | | - |
193 | | -`EventSource` is not available in all browsers. However, there are [several |
194 | | -polyfills available](http://bower.io/search/?q=eventsource). |
195 | | - |
196 | | -## Run the Examples |
197 | | - |
198 | | -Install the dependencies: |
199 | | - |
200 | | -``` |
201 | | -npm install && bower install |
202 | | -# make sure you have gulp installed globally... or |
203 | | -npm install gulp -g |
204 | | -``` |
205 | | - |
206 | | -Event streams don't work with Node compression. To disable compression, delete the entry from `server/middleware.json` so it looks like this: |
207 | | -``` |
208 | | -... |
209 | | -"compression": { |
210 | | - "enabled":false |
211 | | -}, |
212 | | -... |
213 | | -``` |
214 | | - |
215 | | -Build and run the example: |
216 | | - |
217 | | -``` |
218 | | -gulp serve |
219 | | -``` |
220 | | - |
221 | | -Open two separate browser windows and navigate to `http://localhost:3000` in both. |
222 | | - |
223 | | ---- |
224 | | - |
225 | | -[More LoopBack examples](https://loopback.io/doc/en/lb3/Tutorials-and-examples.html) |
0 commit comments