Skip to content

Commit ec8392b

Browse files
committed
Adding EventEmitter stream demo.
1 parent 0d1f745 commit ec8392b

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [EventEmitter Is An RxJS Observable Stream In Angular 2 Beta 6](http://bennadel.github.io/JavaScript-Demos/demos/event-emitter-stream-angular2/)
1314
* [Unhandled Errors In RxJS Observable Streams Will Throw Errors In Angular 2 Beta 6](http://bennadel.github.io/JavaScript-Demos/demos/uncaught-errors-rxjs-angular2/)
1415
* [HTTP Requests Are Cold / Lazy Streams In Angular 2 Beta 6](http://bennadel.github.io/JavaScript-Demos/demos/lazy-http-stream-angular2/)
1516
* [Proving Custom View Templates For Components In Angular 2 Beta 6](http://bennadel.github.io/JavaScript-Demos/demos/consuming-component-api-view-angular2/)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
my-app {
3+
bottom: 0px ;
4+
left: 0px ;
5+
position: fixed ;
6+
right: 0px ;
7+
top: 0px ;
8+
}
9+
10+
my-app div.dot {
11+
background-color: #FF0099 ;
12+
border-radius: 20px 20px 20px 20px ;
13+
box-shadow: 1px 1px 3px #CCCCCC ;
14+
height: 20px ;
15+
position: absolute ;
16+
width: 20px ;
17+
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
6+
<title>
7+
EventEmitter Is An RxJS Observable Stream In Angular 2 Beta 6
8+
</title>
9+
10+
<link rel="stylesheet" type="text/css" href="./demo.css"></link>
11+
</head>
12+
<body>
13+
14+
<h1>
15+
EventEmitter Is An RxJS Observable Stream In Angular 2 Beta 6
16+
</h1>
17+
18+
<my-app>
19+
Loading...
20+
</my-app>
21+
22+
<!-- Load demo scripts. -->
23+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/6/es6-shim.min.js"></script>
24+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/6/Rx.umd.min.js"></script>
25+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/6/angular2-polyfills.min.js"></script>
26+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/6/angular2-all.umd.js"></script>
27+
<!-- AlmondJS - minimal implementation of RequireJS. -->
28+
<script type="text/javascript" src="../../vendor/angularjs-2-beta/6/almond.js"></script>
29+
<script type="text/javascript">
30+
31+
// Defer bootstrapping until all of the components have been declared.
32+
// --
33+
// NOTE: Not all components have to be required here since they will be
34+
// implicitly required by other components.
35+
requirejs(
36+
[ /* Using require() for better readability. */ ],
37+
function run() {
38+
39+
var App = require( "App" );
40+
41+
ng.platform.browser.bootstrap( App );
42+
43+
}
44+
);
45+
46+
47+
// --------------------------------------------------------------------------- //
48+
// --------------------------------------------------------------------------- //
49+
50+
51+
// I provide the root App component.
52+
define(
53+
"App",
54+
function registerApp() {
55+
56+
// Configure the App component definition.
57+
ng.core
58+
.Component({
59+
selector: "my-app",
60+
// Instead of invoking a callback in our host binding, we're
61+
// actually just piping the local event coordinates directly
62+
// into the mouse stream (which we are subscribing to within
63+
// the component controller).
64+
host: {
65+
"(mousemove)": "mouseStream.next({ x: $event.pageX, y: $event.pageY });"
66+
},
67+
template:
68+
`
69+
<div
70+
class="dot"
71+
[style.left.px]="position.left"
72+
[style.top.px]="position.top">
73+
</div>
74+
`
75+
})
76+
.Class({
77+
constructor: AppController
78+
})
79+
;
80+
81+
return( AppController );
82+
83+
84+
// I control the App component.
85+
function AppController() {
86+
87+
var vm = this;
88+
89+
// I hold the position of the dot within the bounds of the component.
90+
vm.position = {
91+
left: -50,
92+
top: -50
93+
};
94+
95+
// As the user moves the mouse, we are going to pipe those (x,y)
96+
// coordinates into this EventEmitter instance.
97+
// --
98+
// NOTE: This is populated with .next() values by the host-binding
99+
// on the app component host element.
100+
vm.mouseStream = new ng.core.EventEmitter();
101+
102+
// Since EventEmitter inherits from RxJS.Subject, which in turn
103+
// inherits from RxJS.Observable, it means that the EventEmitter, in
104+
// Angular 2, is actually an Observable sequence. Which, of course,
105+
// means that we can operate on it and subscribe to it. In this
106+
// stream, we're going to transform the raw mouse coordinates into
107+
// coordinates that can be used to update the view.
108+
// --
109+
// NOTE: This stream is far more complicated than it needs to be - I
110+
// am simply seizing this as an opportunity to experiment with stream
111+
// mechanics and operators.
112+
vm.mouseStream
113+
// Offset the coordinates away from the mouse.
114+
.map(
115+
function offsetFromCursor( coordinate ) {
116+
117+
return({
118+
x: ( coordinate.x - 25 ),
119+
y: ( coordinate.y - 20 )
120+
});
121+
122+
}
123+
)
124+
// Snap the coordinates to a 25x25 grid system.
125+
.map(
126+
function snapToGrid( coordinate ) {
127+
128+
var gridSize = 25;
129+
130+
return({
131+
x: ( coordinate.x - ( coordinate.x % gridSize ) ),
132+
y: ( coordinate.y - ( coordinate.y % gridSize ) )
133+
});
134+
135+
}
136+
)
137+
// Don't pass on the next coordinate value until it has moved
138+
// to another box in the grid system (this one really isn't
139+
// necessary, I'm just experimenting with streams).
140+
.distinctUntilChanged(
141+
function comparator( a, b ) {
142+
143+
return( ( a.x === b.x ) && ( a.y === b.y ) );
144+
145+
}
146+
)
147+
// Log out the value that is being passed onto the subscriber.
148+
// This does not affect the outcome of the value chain.
149+
.do(
150+
function asideNext( value ) {
151+
152+
console.log( "Passing through (%s,%s).", value.x, value.y );
153+
154+
}
155+
)
156+
157+
// Here, we are actually subscribing to the stream of
158+
// coordinates which we are using to update the position of the
159+
// Dot in the view.
160+
// --
161+
// CAUTION: If this were a real-world scenario, we'd have to
162+
// capture this subscription and then unsubscribe to it in the
163+
// ngOnDestroy() life-cycle event handler.
164+
.subscribe(
165+
function handleNext( coordinate ) {
166+
167+
vm.position = {
168+
left: coordinate.x,
169+
top: coordinate.y
170+
};
171+
172+
}
173+
)
174+
;
175+
176+
}
177+
178+
}
179+
);
180+
181+
</script>
182+
183+
</body>
184+
</html>

0 commit comments

Comments
 (0)