-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
848 lines (736 loc) · 33.8 KB
/
index.html
File metadata and controls
848 lines (736 loc) · 33.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>reveal.js</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/atom-one-dark.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<style>
.avatar {
width: 180px;
height: 180px;
border-radius: 100%;
margin: .5em 0;
}
.reveal pre {
margin: 0 auto !important;
font-size: .75em !important;
}
.reveal pre code {
max-height: 700px !important;
}
.reveal .slides section .fragment.highlight-yellow,
.reveal .slides section .fragment.highlight-current-yellow {
opacity: 1;
visibility: inherit;
}
.reveal .slides section .fragment.highlight-yellow.visible {
color: #eef703 !important;
}
.reveal .slides section .fragment.highlight-yellow.visible > span {
color: #eef703 !important;
}
.reveal .slides section .fragment.highlight-current-yellow.current-fragment {
color: #eef703 !important;
}
.reveal .slides section .fragment.highlight-current-yellow.current-fragment > span {
color: #eef703 !important;
}
.reveal .slides > section.cm-title, .reveal .slides > section > section.cm-title {
min-height: 100% !important;
display: flex !important;
flex-direction: column !important;
justify-content: center !important;
position: absolute !important;
top: 0 !important;
}
section div.top {
position: absolute !important;
top: 0 !important;
margin-left: auto !important;
margin-right: auto !important;
left: 0 !important;
right: 0 !important;
}
section div.bottom {
position: absolute !important;
bottom: 0 !important;
margin-left: auto !important;
margin-right: auto !important;
left: 0 !important;
right: 0 !important;
}
.meme {
font-family: impact !important;
font-size: 2.1em !important;
text-transform: uppercase !important;
color: white !important;
letter-spacing: -2px !important;
text-shadow:2px 2px 0 #000,
-2px -2px 0 #000,
2px -2px 0 #000,
-2px 2px 0 #000,
0px 2px 0 #000,
2px 0px 0 #000,
0px -2px 0 #000,
-2px 0px 0 #000,
2px 2px 5px #000 !important;
}
img.nostyle {
margin:0 !important;
background:none !important;
}
.bold {
font-weight:900 !important;
}
.nobold {
font-weight:normal !important;
}
.nomargin {
margin:0 !important;
}
.link {
text-decoration: underline;
color:#3884b9;
}
.li--blank {
list-style: none;
}
</style>
</head>
<body>
<!--
// Transition style
transition: 'slide', // none/fade/slide/convex/concave/zoom
// Transition speed
transitionSpeed: 'default', // default/fast/slow
// Transition style for full page slide backgrounds
backgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom
-->
<div class="reveal">
<div class="slides">
<section>
<img src="images/chris-profile.jpg" class="avatar" />
<h5 style="text-transform:lowercase;">@chrismarx</h5>
<h5 style="text-transform:lowercase;">bit.ly/anglr43</h5>
<img src="images/zross.png" style="height:100px" class="nostyle plain"/>
<aside class="notes">
Hi, I'm chris marx, slides are up now at that link. and quick plug, For those that don't know i work at zev ross
spatial analysis, we're a local data science and geospatial consulting company.
</aside>
</section>
<section data-transition="zoom" data-background-video="images/to_infinity_and_beyond.mov" data-background-video-loop data-background-video-muted class="cm-title">
<div style=" color: #000; padding: 20px;" class="top">
<h2 class="meme">To <img src="images/angular.svg" width="100" style="vertical-align:bottom;" class="plain nostyle"/> 4 / Infinity</h2>
</div>
<div style=" color: #000; padding: 20px;" class="bottom">
<h2 class="meme">And Beyond!</h2>
</div>
<aside class="notes">
I'm talking today about "To angular 4 / infinity and beyond!". All jokes aside, i will be covering
the latest version of angular today, which is 4.
</aside>
</section>
<section data-transition="slide-in" >
<h2>The Mindset</h2>
<ol>
<li>Angular is a framework</li>
<li>Apps are component driven (web-components-ish)</li>
<li>Html templates are still valid html</li>
<li>Opinionated (mostly)</li>
<ol>
<aside class="notes">
Start with the mindset. Here's a top level overview, so mindset, ecosystem, who should use it and what's terrible
</aside>
</section>
<section data-transition="none" data-background-video="images/matrix_framework.mp4" data-background-video-loop>
<div style="background-color: rgba(0, 0, 0, 0.7); color: #fff;">
<h2>The Mindset</h2>
<ol >
<li class="bold">Angular is a framework
<ul class="nobold">
<li>The matrix, I mean framework, provides all</li>
<li>Web components, UI Library, Router, Flex Layout, Animations, CLI, Browser Plugin, AJAX</li>
<li>Isomorpohic Rendering and Pluggable Renderers</li>
</ul>
</li>
</ol>
</div>
<aside class="notes">
number 1 angular is a framework. when you step into the matrix, err i mean start using the framework, the framework
provides all.
You get what are essentially web components, ui library, router, flex layout, animations, cli, browser plugin,
http client for doing ajax, really if it's something that's pretty essential to making a single page app work,
chances are angular is going to at least have some basic support for it.. Obviously if you need a mapping framework like leaflet
or need charts, etc., you're going to include other libraries.
We now also have
Isomorphic rendering, or server side rendering supported and officially part of the angular universe with the
addition of angular universal.
To support that feature, angular now comes with a pluggable rendering system, so now you can even do native apps using
thing like react native, or the more recommended solution is to use nativescript, which is a similar effort.
</article>
</aside>
</section>
<section data-transition="none" >
<h2>The Mindset</h2>
<ol start="2">
<li class="bold"><span class="bold">Apps are component driven (ala web-components-ish)</span>
<ul style="font-weight:normal;">
<li class="link">https://angular.io/tutorial</li>
<li class="link">https://angular.io/guide/router</li>
<li class="link">https://github.com/johnpapa/angular-tour-of-heroes</li>
</ul>
</li>
</ol>
<aside class="notes">
number 2, so Angular is really all about the components now. Angularjs or angular 1 started off with the idea that components were a good thing
but didn't force you to be completely component driven. Now angular is entirely component driven.
For this section, I'm going to be referencing the Angular Tour of Heroes app, which is what all the official
documentation references. it's also what they use to look at advanced topics, and it's very handy to have around
as a reference, you can check it out from that github link.
</aside>
</section>
<section>
<iframe id="demo-iframe" data-src="images/dist/index.html#/dashboard" style="width:95%;height:610px;background-color:white;">
</iframe>
<aside class="notes">
Here's the basic demo app, it's got the router (which also now supports nested routes, optional states, it's very nice),
it's got 2 different primary page views, and then within each view, there are additional components that are built individually
like the search bar, or the hero detail view, which is used across both views. In page routing (and i'm showing the url here since this
is being shown in an iframe), provide deep links to anywhere in the application.
</aside>
</section>
<section>
<pre><code class="stretch" data-trim>
<body>
<my-root></my-root>
</body>
</code></pre>
<aside class="notes">
To put that app on a page, we just include this
</aside>
</section>
<section>
<pre><code class="stretch typescript" data-trim data-noescape>
import { Component } from '@angular/core';
import { Router, Event, NavigationEnd } from "@angular/router";
<span class="fragment highlight-yellow">@Component({</span>
<span class="fragment highlight-yellow">selector:</span> 'my-root',
<span class="fragment highlight-yellow">templateUrl</span>: './app.component.html',
<span class="fragment highlight-yellow">styleUrls:</span> ['./app.component.css']
})
export class AppComponent {
<span class="fragment highlight-yellow">title = 'Tour of Heroes';
urlLocation = "";</span>
constructor(private router: Router){
<span class="fragment highlight-yellow">router.events.subscribe((event:Event) => {</span>
if(event instanceof NavigationEnd) {
<span class="fragment highlight-yellow">this.urlLocation = event.url;</span>
}
});
}
}
</code></pre>
<aside class="notes">
Ok, how does that work. This is the primary app component. There's is not much here, but if you're not familiar with es6 or typescript
it could look like we're not even doing javascript anymore.
1.The component annotation adds both information to angular about what this class is,
as well as a way to set commonly needed information in a nice succint way, rather than
having to extend a super class, call getters, etc.
It's really just a container, but this is where it all begins.
The selector identifies what tag this app will be rendered into. This is basically web-components,
if you put a angle bracket my-root html tag on the page, it will include what u put in this app.
2. the html template
3. the css - all of the styles will automatically be scoped just to apply to this component. this echoes both css modules
and web components. Currently angular can support several different levels of css view encapsulation, even use
native shadow dom if its available.
4.For this demo, I added the event.subscribe, which simply sets up a subscription
to the router events, and when there is a successful navigation it updates the urlLocation class property, which are exposed
to the template. We'll talk more later about how angular handles change detection and knows to update the views.
</aside>
</section>
<section>
<pre><code class="typescript" data-trim>
<h1>{{title}} ----- Show URL:{{urlLocation}}</h1>
<div class="header-bar"></div>
<nav>
<a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
</code></pre>
<aside class="notes">
This is what the html template looks like for this basic component. The curly brackets are replaced
with what the values those variables in the compoennt contain.
You can see we have another custom tag already here, that the router outlet, this is where the different
views of the app will be rendered.
You can see we've got some additional attributes being added to the link elements, those are router specific directives to activate
the other route views, and the router-outlet, where the views will be rendered. you can have many nested router-outlets, which
lets you create whatever kind of ui you want. The router in some ways, is also where angular apps tend to prefer
storing state.
</aside>
</section>
<section>
<pre><code class="typescript" data-trim>
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes,{useHash:true})],
exports: [RouterModule]
})
export class AppRoutingModule { }
</code></pre>
<aside class="notes">
Here's the router config, each route in the application is mapped to a component. You can also setup child routes
even do lazy route loading (which means that other "page views" in your app, and all their resources, (unless they're used elsewhere))
will actually be built into separate files and not loaded until those page views are active (or even can be preloaded in the
background automatically)
I added the useHash here, like all modern apps, angular uses html5 push state, but to embed the app and run without a normal server
i reverted to the old hash-bang syntax, which still works perfectly fine.
</aside>
</section>
<section >
<pre><code class="typescript" data-trim data-noescape>
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'my-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
<span class="fragment highlight-yellow">heroes: Hero[] = [];</span>
constructor(
private router: Router,
private heroService: HeroService) {
}
ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
gotoDetail(hero: Hero): void {
const link = ['/detail', hero.id];
this.router.navigate(link);
}
}
/*just for demo, can also use interfaces here too*/
<span class="fragment highlight-yellow">export class Hero {</span>
id: number;
name: string;
}
</code></pre>
<aside class="notes">
typically each major page view is a component as well. Here the component is setup more typically, with all
the resources in their own files. This is the dashboard, the default view.
4. Notice the array has type "Hero", this is very nice since all the methods are deal with hero records can now expect
exactly what they are getting, and typescript will give type errors immediately, as well as intellisense,
more on that later.
</aside>
</section>
<section>
<h4>./dashboard.component.html</h4>
<pre><code data-trim >
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</div>
</div>
<my-hero-search></my-hero-search>
</code></pre>
<aside class="notes">
and here is the dashboard component's template. notice here that the search bar is split out into
it's own component, since this is a specialized peice of the ui, and could also easily be used in other
areas of the application. So how does your app know though, that this custom component is available?
</aside>
</section>
<section>
<pre><code data-trim >
@Injectable()
export class HeroService {
private heroesUrl = 'app/heroes'; // URL to web api
constructor(private http: Http) { }
getHeroes(): Promise<Array<Hero>> {
return this.http
.get(this.heroesUrl)
.toPromise()
.then((response) => {
return response.json().data as Hero[];
})
.catch(this.handleError);
}
...
</code></pre>
<aside class="notes">
a service, this is where reusable logic, business logic, non view related processing goes.
</aside>
</section>
<section data-background-image="images/homer_frightened2.gif" data-background-transition="concave" data-background-size="100% 100%">
<aside class="notes">
The next slide is usually where people start getting scared. I realize there are unfamiliar terms here
but it's really pretty darn sensical
</aside>
</section>
<section>
<pre><code class="typescript" data-trim data-background-transition="concave" data-transition="concave">
@NgModule({
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
HttpModule,
InMemoryWebApiModule.forRoot(InMemoryDataService, { delay: 600 })
],
declarations: [
AppComponent,
DashboardComponent,
HeroSearchComponent,
HeroesComponent,
HeroDetailComponent,
],
providers: [
HeroService,
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: LocationStrategy, useClass: HashLocationStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule { }
</code></pre>
<aside class="notes">
that's clearly laid out int he main app.module file. The imports section defines what additional
modules you're using (so other entire bundles of elements, services etc), and then also what components
this module declares, as well as what services it can provide. (Those additioanl providers for location I added
to enable the hash location. It is however a nice example of how easy it is to configure the behavior of a module.
if you want to override how a particular service works, or provider an alternate implemetation of the service,
you can define it here for dependency injection (more on that later too)). For large projects, being able to
keep track so concisely of everything that is involved or required by ur module is a life saver.
</aside>
</section>
<section data-transition="none">
<h2>The Mindset</h2>
<ol>
<li>Angular is a framework</li>
<li>Apps are component driven (ala web-components-ish)</li>
<li class="fragment bold">Html templates are still valid html</li>
<p>
</p>
</ol>
<aside class="notes">
To me this was always a selling point for angular, as a developer, I would often get a working
mockup of static html page, and then it would be my job to actually do things. the html and css would
already be pretty much mostly valid, I just need to add the additional logic, loops, filters, etc. Angulars
approach really shines here for that.
</aside>
</section>
<section data-transition="none" data-background-image="images/mrspock.webp" data-background-size="97% 100%">
<h2>The Mindset</h2>
<ol>
<li>Angular is a framework</li>
<li>Apps are component driven (ala web-components-ish)</li>
<li class="bold">Html templates are still valid html</li>
<li class="bold">Opinionated (mostly)</li>
</ol>
<aside class="notes">
Finally, opinionated. Angular is fairly opinionated. You could use it without typescript, but it will be more painful,
as most of the examples are in typescript. rxjs is baked in, and angular basically thinks you should use (and we will see why).
The framework comes with solutions to most problems
and it's easiest to just use them. Angular 2/4 has also taken what I think the wonderful step to produce
an official style guide, for people like me, this is a godsend. I want to send off a developer,
and say, make this component, and i want it to look exactly as if i did it myself,
and i would do it following the styleguide and so can they. Its awesome.
There are some things that angular does leave up to you. For instance, some of the change detection options
</aside>
</section>
<section data-transition="none" data-background-image="images/sinead2.gif" data-background-size="128% 100%">
<h2>The Mindset</h2>
<ol>
<li>Angular is a framework</li>
<li>Apps are component driven (ala web-components-ish)</li>
<li class="bold">Html templates are still valid html</li>
<li class="bold">Opinionated (mostly)
<ul class="nobold">
<li class="fragment grow highlight-green">Change Detection</li>
</ul>
</li>
</ol>
<aside class="notes">
Change detection - is all about how these frameworks compare some current state with some new state
and figure out if something has changed, and whether there needs to be some re-rendering of the dom.
Maybe add slide with figures here. Afai understand it, React treats all data as immutables, and
so if you want the data to update, you pass it a new object, and it can tell the different with
straight object equality, it then renders the dom virtually, diffs, and then renders the changed areas.
Vue is a bit more like angular, where you specify which properties count as important data in your data config
and those are the only values that are watched for changes, and then diffed with virtual dom.
Angular actually gives you choices here. You can stick to the easiest method, which we saw earlier, and just
have angular build a change detection class for each of your componenets, and it will figure out
what data can change, and watch everything, and update the values in the dom accordingly. Or, you
can tell angular that you are going to use immutable.js, and it will only look at changes based on
object equality. Or you can go with rxjs, and use observables for data that will change. In the later
2 cases, you can also tell angular to only search the component trees that are strictly affected by your
changes.
You're also free of course to use ngrx, which is a unidirectional data store just like react, and you
get the history and everything (i havent used it).
</aside>
</section>
<section data-background-image="images/matrix_flying.gif" data-background-size="80% 50%">
<aside class="notes">
I realize that was alot, so i'm going to fly through the rest of this
</aside>
</section>
<section >
<h2>The Ecosystem</h2>
<ol>
<li>Typescript</li>
<li>CLI, Webpack</li>
<li>RxJS</li>
<li>Dependency Injection</li>
<li>NgRx (optional)</li>
<li>Angular Material</li>
<li>Angular Universal</li>
<li>Nativescript / React Native</li>
<li>Augury</li>
</ol>
<aside class="notes">
alright, yeah, that is a lot, we're flying now
</aside>
</section>
<section>
<h2>1. Typescript</h2>
<div class="stretch">
<img src="images/typescript_coding.gif" style="height:60%; width:100%;"/>
</div>
<aside class="notes">
I think typescript has basically won. Typescript gives you es6 transpilation like babel, but
it also gives you types, and features from javascript next (es7 ,etc)
but wait, you didn't even add any types! i like this example best from typescript, because people
are always afraid, like, oh, i'm going to spend all day writing string and number etc. nope. duck typing ftw!
</aside>
</section>
<section data-background-transition="zoom" data-background-image="images/ducktyping.jpg" data-background-size="100% 100%">
<aside class="notes">
typescript also gives you tooling like you would expect in a static language with an ide (even though i just use atom)
you can automatically resolve the es6 imports for instance, and not waste time manually including all those import statements
</aside>
</section>
<section>
<h2>2. CLI</h2>
<div class="stretch">
<video controls loop>
<source data-src="images/cli_final.mov" />
</video>
</div>
<aside class="notes">
ok, so here's the cli, it's sped up a bit, but this is no more than a minute or 2 in reality. here we go, you
make a new app. angular creates everything u need, all the typescript configuration, the webpack, all the default
packages u need for both dev and production. and then u can serve it with an angular node server, already
configured with live reload while you're working, including ahead-of-time compiling or aot, that means
you do get error checking in your templates just like react, even though we dont have to use the specialized
jsx syntax. when u add components or services or whatever, angular automatically adds them to ur module
definition too. and when you're ready to ship your app, u just hit another command, and u get a complete
bundle thats minified, uglified, tree shaken, all extra dependecnies or unused code removed, revved and ready
to go, even with environment specific variables, etc.
</aside>
</section>
<section>
<h2>RXJS</h2>
<pre><code data-trim data-noescape>
search(term: string): void {
// Push a search term into the observable stream.
this.searchTerms.next(term);
}
ngOnInit(): void {
this.heroes = this.searchTerms
<span class="fragment highlight-yellow">.debounceTime(300)</span> // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // return the http search observable or the observable of empty heroes if no search term
? this.heroSearchService.search(term)
: Observable.of<Hero[]>([]))
.catch(error => {...});
}
/* or */
search(term: string): Observable<Hero[]> {
return this.http
.get<Heror>(`app/heroes/?name=${term}`)
<span class="fragment highlight-yellow">.retry(3)</span>
.catch((error: any) => {
console.error('An friendly error occurred', error);
return Observable.throw(error.message || error);
});
}
</code></pre>
<aside class="notes">
Reactive Extensions for JS
handling asnychronous streams of data
</aside>
</section>
<section data-background-image="images/material.png" data-background-size="100% 83%">
</section>
<section>
<h2>Augury</h2>
<div class="stretch">
<video controls loop data-autoplay>
<source data-src="images/augury.mov" />
</video>
</div>
</section>
<section data-transition="none" >
<h2>When to use this framework</h2>
<ol class="stretch">
<li>You like Typescript</li>
<li class="fragment">Bigger projects (mostly)</li>
<li class="li--blank"> </li>
<li class="li--blank"> </li>
</ol>
<aside class="notes">
1. bigger projects - although once you get to know it, there really isnt any reason to use it for smaller apps either
2. typescript
</aside>
</section>
<section data-transition="none" data-background-image="images/futurama.jpg" data-background-size="100% 100%" >
<h2>When to use this framework</h2>
<ol class="stretch" style="background-color: rgba(0, 0, 0, 0.5);">
<li>You like Typescript</li>
<li>Bigger projects (mostly)</li>
<li>You don't like having to make a lot decisions</li>
<li class="li--blank"> </li>
</ol>
<aside class="notes">
1.
</aside>
</section>
<section data-transition="none" data-background-image="images/troll-face.jpg" data-background-size="35% 35%" data-background-position="52% 100%" >
<h2>When to use this framework</h2>
<ol class="stretch" >
<li>You like Typescript</li>
<li>Bigger projects (mostly)</li>
<li>You don't like having to make many decisions</li>
<li>You like being faster than React :P</li>
</ol>
<aside class="notes">
1. bigger projects - although once you get to know it, there really isnt any reason to use it for smaller apps either
2. typescript
</aside>
</section>
<section data-transition="none" data-background-image="">
<h2>When cont.</h2>
<ol start="5">
<li class="fragment" data-fragment-index="1">You want a framework that is not going away (supported by google)</li>
<li class="fragment" data-fragment-index="3">You want a job</li>
</ol>
<video class="fragment" data-fragment-index="2" data-autoplay loop>
<source data-src="images/made_with_angular.mov" />
</video>
<img src="images/jobs.png" style="height: 36%;position: absolute;top: 267px;width: 116%;left: 0px;" class="fragment" data-fragment-index="3"/>
<sub class="fragment" data-fragment-index="3">https://www.indeed.com/jobtrends/q-react.js-q-angular.js-q-ember.js-q-backbone.js-q-vuejs.html</sub>
<aside class="notes">
5. you want a framework that is not going away, will remain supported and actively developed (google), with new technology choices
by google engineers. And you want to use a framework used by paypal, hbo, sony, tesla, etc, and of course google
6. You want a job
</aside>
</section>
<section data-transition="none" >
<h2>What is terrible</h2>
<ol>
<li>Really good at all its setup to do, not so good for other things...</li>
<li>People say there is a learning curve</li>
<li>Everything is still a little bleeding edge</li>
<li>There is magic going on</li>
<!-- no so terrible anymore -->
<li>But but the imports and the crazy dependency injection! (Hero)</li>
<li>The size!</li>
<li>The speed!</li>
</ol>
<aside class="notes">
As long as you don't try to do something crazy, like create your own angular library, so you can resuse
a set of components and service across apps.
bleeding edge - material library hasn't fully implemented everythign from the angular 1 version
but there are also other ui libs out there too
imports! dependency injection! with typescript, as soon as u write something like Hero
any ide (even things like atom, which is what i use), can now automatically resolve the class
and add the import statements for you. and we saw how the cli can update your depenncy injection
too, so i think the cries of, BUT BOILERPLATE! are over rated at this pooint, and honestly,
for a big application, i want to be tracking the kinds of things u are able to track there.
we saw the basic size, but even tour of heroes, with rxjs, etc. was 94kb for all the main js and libraries.
speed - if we have time.
</aside>
</section>
<section data-transition-speed="fast" data-background-image="images/delorian.gif">
<h2>Bonus! Lightning Round!</h2>
<div style="background-color: rgba(0, 0, 0, 0.4); color: #fff; padding: 20px;">
<p><a target="_blank" href="http://www.stefankrause.net/js-frameworks-benchmark6/webdriver-ts-results/table.html">
http://www.stefankrause.net/js-frameworks-benchmark6/webdriver-ts-results/table.html</a></p>
<p><a target="_blank" href="http://www.stefankrause.net/js-frameworks-benchmark6/vue-v2.3.3-non-keyed/">
http://www.stefankrause.net/js-frameworks-benchmark6/vue-v2.3.3-non-keyed/</a></p>
<p><a target="_blank" href="http://www.stefankrause.net/js-frameworks-benchmark6/angular-v4.1.2-non-keyed/">
http://www.stefankrause.net/js-frameworks-benchmark6/angular-v4.1.2-non-keyed/</a></p>
<p><a target="_blank" href="http://www.stefankrause.net/js-frameworks-benchmark6/react-v15.5.4-redux-v3.6.0/">
http://www.stefankrause.net/js-frameworks-benchmark6/react-v15.5.4-redux-v3.6.0/</a></p>
</div>
<aside class="notes">
In many ways, all these frameworks are all doing similar things for you. The question as i see it are
who do you want to invest in, which technologies do you like to use, what approaches do you like better
to some of the thigns like html templating or change detection.
</aside>
</section>
<section>
<h2> Questions </h2>
<img src="images/chris-profile.jpg" class="avatar" />
<h5 style="text-transform:lowercase;">@chrismarx</h5>
<h5 style="text-transform:lowercase;">bit.ly/anglr43</h5>
<img src="images/zross.png" style="height:100px" class="nostyle plain"/>
<aside class="notes">
Thank you
</aside>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
history:true,
minScale: .8,
/* might need this - https://github.com/hakimel/reveal.js#presentation-size*/
/*width: "100%",
height: "100%",
margin: 0,
minScale: 1,
maxScale: 1,*/
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>