-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
1122 lines (1082 loc) · 55 KB
/
index.html
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
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular-intro :: Introduction to AngularJS</title>
<meta name="description" content="introduction to ANgularJS for the Adept/Intermediate at programming">
<meta name="author" content="Rhett Lowe">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/reveal.min.css">
<link rel="stylesheet" href="css/theme/default.css" id="theme">
<link rel="stylesheet" href="css/slideStyles.css" id="theme-add">
<!-- For syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- If the query includes 'print-pdf', use the PDF print sheet -->
<script>
document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides" ng-app="slides">
<section id="opening">
<section>
<img class="logo" src="images/AngularJS-large.png" />
<h3>More Dynamic - Less Work</h3>
</section>
<section>
<!-- founder -->
<img class="column two" src="images/Misko8.jpg" title="Misko Hevery" alt="Misko Hevery" />
<div class="column two left-align">
<h2>Misko Hevery</h2>
<ul>
<li>Founder</li>
<li>Google Employee</li>
<li>Agile Coach</li>
<li>Automated <br /> Testing Expert</li>
</ul>
<br />
<br />
<ul>
<li><a href="http://misko.hevery.com/about/">Website</a></li>
<li><a href="https://github.com/mhevery">GitHub</a></li>
<li><a href="https://plus.google.com/112540226618013533507/posts">Google+</a></li>
<li><a href="http://stackoverflow.com/users/192810/misko-hevery">Stack Overflow</a></li>
<li><a href="https://twitter.com/mhevery">Twitter</a></li>
<li><a href="http://www.linkedin.com/pub/misko-hevery/0/3b1/388">LinkedIn</a></li>
</ul>
</div>
<aside class="notes" >
<ul>
<li>Originally written as a 20% project to speed up the development time of some google
internal websites.
</li>
<li>is a testing expert</li>
<li>Teaches unit and end-to-end testing to google employees.</li>
</ul>
</aside>
</section>
<section>
<!-- released -->
<h1>History</h1>
<table>
<tr>
<td>Concept:</td>
<td></td>
<td>2009</td>
</tr>
<tr>
<td>Original Release</td>
<td>0.9.0</td>
<td>Oct 20, 2010</td>
</tr>
<tr>
<td>Most Common</td>
<td>1.0.8</td>
<td>Aug. 22, 2013</td>
</tr>
<tr>
<td>Current Stable</td>
<td>1.2.1</td>
<td>Nov. 14, 2013</td>
</tr>
</table>
</section>
<section>
<h2>Most notable features</h2>
<ul>
<li>Two way binding</li>
<li>End-to-end testing</li>
<li>MVC / MVW</li>
<li>Re-usable Components</li>
</ul>
<ul>
<li>Declarative</li>
<li>Extends HTML</li>
<li>Dependency Injection</li>
<li>Q & Promises/A+</li>
</ul>
<aside class="notes">
<p>These are some of the features Angular is most notable for currently, but they are not
why it was originally written. It was written just to be fast to develop and easily
testable.
</p>
</aside>
</section>
<section>
<!-- Quick blurb about MVC -->
<h2>MVW: Model / View / Whatever</h2>
<aside class="notes">
<p>Now we will review MVC theory and how AngularJS sees MVC</p>
</aside>
</section>
</section>
<section id="the-view">
<section>
<h1>MVC: The View</h1>
<aside class="notes">
<p>The first part to look at is the view in my opinion. AngularJS really looks at the view
differently the most other frameworks out there, esp. jQuery.
</p>
</aside>
</section>
<section>
<h2>In AngularJS the View:</h2>
<ul>
<li>Is a First Class Citizen!</li>
<li>Controls where data goes</li>
<li>Controls User-Interactivity</li>
<li>Dictates the Final State of the Data</li>
</ul>
<aside class="notes">
Nothing but what is on the slide
</aside>
</section>
<section class="take-out">
<h2>AngularJS View vs. jQuery View</h2>
<p>
<strong>jQuery:</strong>
HTML/View is an anchor point so jQuery can insert DOM as it sees fit
</p>
<aside class="notes">
<p>We all know jQuery and how it interacts with the DOM. </p>
<ul>
<li>Write an anchor point in the DOM using CSS Selectors, ID, Class and Tag</li>
<li>In jQuery, select the anchor and manipulate it however the JS controller sees fit.</li>
<li>The DOM/View doesn't have any control over what is placed inside</li>
<li>meaning Designers MUST understand JavaScript to fully code a page.</li>
</ul>
<p>In AngularJS</p>
<ul>
<li>The Controller exposes editable points</li>
<li>The DOM/View Uses those points as it sees fit.</li>
<li>The View decides where loops, dynamic titles, and JS Dropdowns go</li>
<li>The Controller allows special functions, but eh view decides when and where they are
used.
</li>
</ul>
</aside>
</section>
<section>
<h2 ng-non-bindable>Hello {{ who }}</h2>
<div ng-app>
Hello {{ who }}!<br /><br />
<input ng-model="who" type="text"/>
</div>
<aside class="notes">
<p>In this example, I am ONLY using the view. Nothing more nothing less.</p>
<p>I have assigned part of the DOM to listen to a variable named `$scope.who` and an input
to manipulate `$scope.who`
</p>
</aside>
</section>
<section>
<h2>How it works</h2>
<pre ng-non-bindable><code data-trim>
<div ng-app>
Hello {{ who }}!<br /><br />
<input ng-model="who" type="text"/>
</div>
</code></pre>
<aside class="notes">
<p>This is the whole code. Notice:</p>
<ul>
<li>ng-app</li>
<li>Template Handlebars `{{ }}`</li>
<li>ng-model</li>
</ul>
</aside>
</section>
<section>
<h2>Introducing</h2>
<ul>
<li>ng-app</li>
<li ng-non-bindable>{{ expression }}</li>
<li>ng-model</li>
<li>$scope</li>
</ul>
<aside class="notes">
<ul>
<li>ng-app tells AngularJS what ITS DOM elements are so it knows what to work with and
what to ignore.
</li>
<li>The handlebars tell angular where to bind readable data. Can also do functions,
math, and ternary statements
</li>
<li>ng-model creates a 2-way link to allow for editing data</li>
<li>Abstraction Layer ==> see next slide</li>
</ul>
</aside>
</section>
<section>
<h2><pre class="inline"><code data-trim>$scope</code></pre></pro></h2>
<ul>
<li>Abstraction Layer</li>
<li>
<pre class="inline"><code data-trim>null</code></pre>
default
</li>
<li>2-way binding</li>
</ul>
<aside class="notes">
<ul>
<li>The `$scope` is an abstraction layer which makes it easier to interact with public
controller data and functions and utilizes dirty-data-checking
</li>
<li>All uninitialized variables start out as `null`. Null equates to a blank string or a
zero int
</li>
<li>Because of dirty checking, `$scope` can be set from Controller OR View and be
reflected everywhere.
</li>
</ul>
</aside>
</section>
</section>
<section id="the-view-2" ng-app>
<section>
<h1>MVC: The View</h1>
<h2>Part 2</h2>
<aside class="notes">
<p>The view has many more parts to it. Templates and Models are just the beginning.</p>
</aside>
</section>
<section>
<h2>Hello World</h2>
<div>
List the people you want to say hello to:<br /><br />
<input ng-list ng-model="who" type="text"/> <br />
<ul>
<li ng-repeat="person in who">
Hello {{person}}!
</li>
</ul>
</div>
<aside class="notes">
<p>AngularJS has built in functions to help simplify changing data types. In this example
we:
</p>
<ul>
<li>transfer a comma separated list to an array of strings in the `$scope`</li>
<li>Have a repeater say hello to each person on the list</li>
<li>Ignore all non names: ex '', ','</li>
<li>Demonstrate Directives</li>
</ul>
</aside>
</section>
<section>
<h2>How it works</h2>
<pre ng-non-bindable><code data-trim>
<div ng-app>
List the people you want to say hello to:<br /><br />
<input ng-list ng-model="who" type="text"/> <br />
<ul>
<li ng-repeat="person in who">
Hello {{person}}!
</li>
</ul>
</div>
</code></pre>
<aside class="notes">
<ul>
<li>ng-list is an example of a directive.</li>
<li>Directives are AngularJS code which modify the normal behavior of a DOM element.
Often they can have their own scope and can modify the WHOLE look of an element
</li>
<li>
Notice
<ul>
<li>ng-list</li>
<li>ng-repeat</li>
</ul>
</li>
</ul>
</aside>
</section>
<section>
<h2>Introducing</h2>
<ul>
<li>ng-list</li>
<li>ng-repeat</li>
</ul>
<aside class="notes">
<ul>
<li>Directive ng-list takes in a string of comma separated values, splits, trims,
reduces, and outputs an array of strings
</li>
<li>Directive ng-repeat automates a for loop tied to the `$scope` for every item added
to the array or object a new child is created. The same goes for removing objects
</li>
<li>ng-repeat works for arrays AND objects but has different syntax for each.</li>
<li>Arrays are easier to use with ng-repeat</li>
</ul>
</aside>
</section>
<section>
<h2>How many is that?</h2>
<p>You said hello to {{ who.length }} people</p>
<p>You said hello to <ng-pluralize count="who.length || 0"
when="{'0': 'nobody?!?!',
'one': '1 person.',
'other': '{} people!'}"></ng-pluralize></p>
<input ng-model="who" type="text" ng-list/>
<aside class="notes">
Notice:
<ul>
<li>Counting the people in `$scope.who` array.</li>
<li>Pluralization for 0, 1 and >1</li>
<li>Multiple use of the same variable in the view</li>
</ul>
</aside>
</section>
<section>
<h2>Great but minor splendors</h2>
<pre ng-non-bindable><code data-trim>
<p>You said hello to {{ who.length }} people</p>
<p>
You said hello to
<ng-pluralize count="who.length || 0" when="{'0': 'nobody?!?!',
'one': '1 person.',
'other': '{} people!'}"></ng-pluralize>
</p>
<input ng-model="who" type="text" ng-list/>
</code></pre>
<ul>
<li ng-non-bindable>{{ who.length }}</li>
<li>ngPluralize</li>
<li>Multiple uses of
<pre class="inline"><code data-trim>$scope.who</code></pre>
</li>
</ul>
<aside class="notes">
<ul>
<li>{{ who.length }} is standard javascript for finding # of elements in an array.</li>
<li>ngPluralize is allowing for correct grammar in areas where it is needed. ngPluralize
also includes advanced functionality
</li>
<li>ngPluralize is also a directive. Notice that directives can be Tags, Attributes,
Classes or even Comments
</li>
<li>`$scope.who` has been referenced here 3 times. It can be referenced as many times as
you like pretty much.
</li>
<li>Example of a short-circuit in the wild. This one says who.length, unless who does
not exist or is not an array, in that case use 0
</li>
</ul>
</aside>
</section>
<section>
<h2>Trim the fat ...</h2>
<div ng-init="people = [
{name:'Rhett'},
{name:'Ali'},
{name:'Ray'},
{name:'Maria'},
{name:'Jannah'},
{name:'Naz'},
{name:'David'}
]">
Only These people:<br /><br />
<input ng-model="onlyMe" type="text"/><br />
<ul>
<li ng-repeat="person in people | filter:onlyMe">
Hello {{person.name}}!
</li>
</ul>
</div>
<aside class="notes">
<p>Notice here that anything you type in will limit the output of the repeat. It is using
filters to modify the array before the repeat get it.
</p>
</aside>
</section>
<section>
<h2>How it works</h2>
<pre ng-non-bindable><code data-trim>
<div ng-init="people = [
{name:'Rhett'},
{name:'Ali'},
{name:'Ray'},
{name:'Maria'},
{name:'Jannah'},
{name:'Naz'},
{name:'David'}
]">
Only These people:<br /><br />
<input ng-model="onlyMe" type="text"/><br />
<ul>
<li ng-repeat="person in people | filter:onlyMe">
Hello {{person.name}}!
</li>
</ul>
</div>
</code></pre>
<aside class="notes">
<p>Notice</p>
<ul>
<li>ng-init creating the initial list of people</li>
<li>the input is tied to `$scope.onlyMe`</li>
<li>the repeat is followed by `| filter:onlyMe`</li>
</ul>
</aside>
</section>
<section>
<h2>Introducing</h2>
<ul>
<li>ng-init</li>
<li>
| (pipe)
<ul>
<li>filter</li>
<li>currency</li>
<li>date</li>
<li>orderBy</li>
<li>Etc...</li>
</ul>
</li>
</ul>
<aside class="notes">
<p>Notice: </p>
<ul>
<li>ngInit - As soon as angular loads this section of the DOM into memory, it round the
code in ngInit</li>
<li>Pipe works just like in linux to pass the argument before it into the command after
it.
<ul>
<li>filter will show only matching text</li>
<li>currency expects a number and outputs currency to your specifications.</li>
<li>date formats a JS Date object or milliseconds since epoch and formats it how
you define
</li>
<li>orderBy will order by the object attribute you specify in ASC or DESC
orders
</li>
<li>Many many more.</li>
</ul>
</li>
</ul>
</aside>
</section>
</section>
<section id="the-view-3">
<section>
<h1>MVC: The View</h1>
<h2>Part 3</h2>
<aside class="notes">
<p>We are nearly done with the view and its powers. But the view can do so much more! By
now I hope you are getting that the view has a lot of power in AngularJS
</p>
</aside>
</section>
<section>
<h2>Clicks are declarative</h2>
<h3>Counter: {{ counter }}</h3>
<span ng-click="counter = 0"><span>Reset</span></span><br />
<a ng-click="counter = counter + 1"><a>+1</a></a><br />
<button ng-click="counter = counter + 5"><button>+5</button></button>
<aside class="notes">
<p>Notice</p>
<ul>
<li>Functions are called dispite clicking on span, anchor, or button</li>
<li>anchors automatically prevent default</li>
<li>none of this is outside the view</li>
</ul>
</aside>
</section>
<section>
<h2>How it works</h2>
<pre ng-non-bindable="$ng-non-bindable$"><code data-trim="$data-trim$">
<h3>Counter: {{ counter }}</h3>
<span ng-click="counter = 0">Reset</span><br />
<a ng-click="counter = counter + 1">+1</a><br />
<button ng-click="counter = counter + 5">+5</button>
</code></pre>
<aside class="notes">
<p>This is the phone code. </p>
<ol>
<li>A counter is set as `$scope.counter`</li>
<li>two click handlers are set in place to increment the counter</li>
<li>one click event sets it to zero</li>
</ol>
</aside>
</section>
<section>
<h2>Introducing ng-click</h2>
<ul>
<li>
<pre class="inline"><code>ng-click="myFunc(variable)"</code></pre>
</li>
<li>
<pre class="inline"><code>ng-click="variable = variable + 1"</code></pre>
</li>
<li>
<pre class="inline"><code>ng-click="variable = variable + 1; myFunc(variable)"</code></pre>
</li>
</ul>
<aside class="notes">
<p>ngClick is a directive with many traits. It can:</p>
<ul>
<li>Run a function attached to the `$scope`</li>
<li>Run a direct command operating on elements in the `$scope`</li>
<li>Do Both</li>
</ul>
<p>It also has built in that any anchor or button with ng-click will automatically prevent
default.
</p>
</aside>
</section>
<section>
<h2>Other directives</h2>
<ul>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngClass">ngClass</a></li>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngShow">ngShow</a>
/ <a href="http://docs.angularjs.org/api/ng.directive:ngBlur">ngHide</a>
</li>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngSrc">ngSrc</a></li>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngFocus">ngFocus</a></li>
</ul>
<ul>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngHref">ngHref</a></li>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngSwitch">ngSwitch</a></li>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngCloak">ngCloak</a></li>
<li><a href="http://docs.angularjs.org/api/ng.directive:ngBlur">ngBlur</a></li>
</ul>
<aside class="notes">
<p>Here is a list of other directives that are extremely useful to the view.</p>
<ul>
<li>ngClass will turn on 1 or more classes dynamically based on either strings or
boolean statements
</li>
<li>ngHref will help anchors dynamically link to the right place by altering the href of
a link according to your template
</li>
<li>ngShow will show a node based on a boolean statement. Hide does the opposite</li>
<li>ngSwitch works almost like a switch case for the view</li>
<li>ngSrc is exactly like ngHref for images</li>
<li>ngCloak hides unwanted elements from view UNTIL angular has loaded.</li>
<li>ngFocus works exactly like ngClick but when someone focuses on an element</li>
<li>ngBlur does the same as ngClick and ngFocus but on blur.</li>
</ul>
<p>There are many more. To read more about these directives and others, click on any of the
directives</p>
</aside>
</section>
</section>
<section id="the-controller">
<section>
<h1>MVC: The Controller</h1>
<aside class="notes">
<p>The controller is just as powerful as the View and is as testable, but only if it is used
properly.
</p>
<ul>
<li>AngularJS Controller !== jQuery Code. Don't try to use them the same way.</li>
<li>AngularJS Controller should be used to initialize data and set up function for the
view.
</li>
<li>Don't try to control the View directly the controller should try to work like an API
making some things public and leaving some things private
</li>
</ul>
</aside>
</section>
<section>
<h2>ng-controller</h2>
<pre ng-non-bindable><code data-trim class="">
<div ng-app ng-controller="myAppCtrl">
{{ variable }}
<span ng-click="myFunc('This will appear in an alert')">Click Me</span>
</div>
</code></pre>
<pre ng-non-bindable><code data-trim class="javascript">
var myAppCtrl = function($scope){
$scope.variable = 'Anything I want';
$scope.myFunc = function(text){
alert(text);
};
};
</code></pre>
<aside class="notes">
<p>the top is in the view and the bottom is in the controller</p>
<ul>
<li>See the top uses ngController to link this section of code to either a function
stored in cache as `myAddCtrl` OR a function named myAppCtrl
</li>
<li>`$scope` is a parameter of the controller function</li>
<li>{{ variable }} in the view === `$scope.variable` in the controller</li>
<li>This also demonstrates how variables may be sent back to the controller's functions through the view</li>
</ul>
</aside>
</section>
<section>
<h2>Controller Structure</h2>
<pre ng-non-bindable><code data-trim class="javascript">
function myController($scope, $timeout, myFactory){
// Variable Instantiation
var a, b, c;
var obj = {};
var fac = new myFactory();
// Function Instantiation
var myFunc = function(text){
alert(text);
}
var initFunc = function(){
//do initialization stuff here
}
// Scope Instantiation
$scope.myVar = 1;
$scope.obj = {name: "test"};
$scope.myFunc = myFunc;
$scope.round = Math.round;
$scope.addAB = function(){
$scope.myVar = a + b;
}
// Initiate processes or data with functions
initFunc();
fac.init();
}
</code></pre>
<aside class="notes">
<p>This is how I like to structure my Controllers.</p>
<ul>
<li>I like to group variables together</li>
<li>group functions together</li>
<li>group scope related declarations together</li>
<li>and always put initialization scripts at the bottom</li>
</ul>
<p>The order isn't all important, but I really prefer instantiation and declaration at top
and function initialization at that bottom.
</p>
<p>Notice</p>
<ul>
<li>I am pulling in more than the scope</li>
<li>`$timeout` is another helper object</li>
<li>i can also pull in models and other data</li>
<li>that order is not important, angular takes care of placing the right objects where
you ask for them
</li>
</ul>
</aside>
</section>
<section>
<h2>NOT JQUERY</h2>
<pre ng-non-bindable><code data-trim class="javascript">
function myController($scope, $timeout, myFactory){
var el = angular.element('#someID');
el.find('div').hide();
}
</code></pre>
<h2>No really don't do this!!</h2>
<aside class="notes">
<p>The controller doesn't work like jQuery. It isn't for writing random code to change the
DOM. Instead use it to allow the DOM/View to make it's own changes.
</p>
<ul>
<li>This code will be impossible to test</li>
<li>disrupt Angular's groove making angular angry</li>
<li>Sometimes the cheating way is to initialize a jQuery object from the controller but
best recommendation is just don't use jQuery at all. Try to put all DOM manipulation
in the View or a directive
</li>
</ul>
</aside>
</section>
</section>
<section id="ng-app">
<section>
<h1>The Application</h1>
<h2>Putting it all together</h2>
<aside class="notes">
Lets talk about how an application fits together modularly.
</aside>
</section>
<section>
<h2>Creating an application and module</h2>
<pre ng-non-bindable><code data-trim class="html">
<div ng-app="myApp" ng-controller="myAppCtrl">
{{ variable | whatsMyName }}
<span ng-click="myFunc('This will appear in an alert')">Click Me</span>
</div>
</code></pre>
<pre ng-non-bindable><code data-trim class="javascript">
angular.module('myApp', [])
.filter('whatsMyName', [function(){
return function(input){
return input + " is my name!";
}
}])
.controller('myAppCtrl', ['$scope', function($scope){
$scope.variable = 'Anything I want';
$scope.myFunc = function(text){
alert(text);
};
}]);
</code></pre>
<aside class="notes">
<p>In this example notice the scafholding for the application.</p>
<ul>
<li>ng-app links the application to the module</li>
<li>ng-controller is still linking the controller to the DOM</li>
<li>we attached a new filter call `whatsMyName` to the application and used it in the
View
</li>
<li>the `.module('name', requisites)` format. Later in actual examples I'll show you how
this works
</li>
</ul>
</aside>
</section>
</section>
<section id="directives">
<section>
<h1>Directives</h1>
<h2>Extending HTML</h2>
<aside class="notes">
<p>Directives are for altering HTML or creating new behaviors in HTML</p>
<p>examples of when one might make a directive</p>
<ul>
<li>Making a spinner input</li>
<li>making a popup box</li>
<li>making custom dropdown menus</li>
<li>Making Popovers</li>
<li>Any place where one migth want a repeatable object that instantiates and de-instantiates itself</li>
</ul>
</aside>
</section>
<section>
<h2>Spinner object</h2>
<pre ng-non-bindable><code data-trim class="html">
<input spinner ng-model="count" min="-5" max="5" />
</code></pre>
<pre ng-non-bindable><code data-trim class="javascript">
angular.module('myApp', []).directive('spinner', [function(){
return {
restrict: 'A',
scope: {
currentNum: '=ngModel',
min: '@?',
max: '@?',
inc: '=?'
},
replace: true,
template:
'<div class="spinner">' +
'<input ng-model="currentNum" />' +
'<span class="plusOne" ng-click="add(inc)">' +
'<i class="chevron-up"></i>' +
'</span>' +
'<span class="minusOne" ng-click="subtract(inc)">' +
'<i class="chevron-down"></i>' +
'</span>' +
'</div>',
link: function(scope, iElement){
if (typeof scope.min === 'undefined'){
scope.min = -1000000000000000;
}
if (typeof scope.max === 'undefined'){
scope.max = 1000000000000000;
}
if (typeof scope.inc === 'undefined'){
scope.inc = 1;
}
scope.add = function(num){
var newNum;
num = (typeof num === 'undefined' ? 1 : num);
if (num + scope.currentNum > scope.max){
newNum = scope.max
} else {
newNum = num + scope.currentNum;
}
scope.currentNum = newNum;
};
scope.subtract = function(num){
var newNum;
num = (typeof num === 'undefined' ? 1 : num);
if (scope.currentNum - num < scope.min){
newNum = scope.min
} else {
newNum = scope.currentNum - num;
}
scope.currentNum = newNum;
};
}
}
}]);
</code></pre>
<aside class="notes">
<p>First notice:</p>
<ul>
<li>Directives must be in an application/module</li>
<li>Restrict: 'A' will restrict the directive to only work when 'spinner' is an
attribute as opposed to Element, Class or Comment
</li>
<li>It creates its own child scope and sets some variables by default</li>
<li>The DOM template is loaded here OR using a templateURL</li>
<li>Link is the function runs just after the template is compiled and replaces the
original DOm element
</li>
<li>Inside the Link:
<ul>
<li>Link function takes in the scope and the container element</li>
<li>I initialize uninitialized variables</li>
<li>and add some helper functions that would normally be on the controller</li>
<li>While I can add a controller to this whole thing, I don't feel the need if
since my overall work is so small
</li>
</ul>
</li>
</ul>
<p>We can ise the spinner directive anywhere within the ngApp as name times as we like.</p>
</aside>
</section>
<section>
<h2>Recommendations and Best practices:</h2>
<ul>
<li>Manipulate the DOM here NOT in Controller</li>
<li>Keep as self enclosed as possible</li>
<li>Directives CAN communicate upwards but life is easier when they don't</li>
</ul>
<aside class="notes">
<ul>
<li>There is nothing wrong with using jQuery or other JavaScript DOM manupulation. It
should almost all happen here in the directive.
</li>
<li>The more enclosed and encapsulated the easier to test and debug.</li>
<li>Directives can emit events which controllers can listen for, but again they can make testing frustrating</li>
<li>Directives can be as simple or as complicated as you want</li>
</ul>
</aside>
</section>
</section>
<section id="providers">
<section>
<h1>MVC: The Model</h1>
<h2>Providers</h2>
<aside class="notes">
<p>Providers are the model. There are several types of providers.</p>
</aside>
</section>
<section>
<p>Provider Types</p>
<ul>
<li>Values</li>
<li>Constants</li>
<li>Factories</li>
<li>Services</li>
<li>Providers</li>
</ul>
<aside class="notes">
<p>There are different types of providers that are ment to do different things</p>
<ul>
<li>Values are instantiated after most other objects but before controllers. Singleton</li>
<li>Constants are always the first to be instantiated. They should be objects. Singleton</li>
<li>Factories are instantiated inside of the controller. You can make as many of them as
you like.
</li>
<li>Services are instantiated before controllers and are Singletons</li>
<li>All of these are providers. When creating any of them, the provider function is
called and produces the final object.
</li>
</ul>
</aside>
</section>
<section>
<h2>Factories and Services</h2>
<ul>
<li>Encapsulate</li>
<li>Feel free to put getters, setters and storage inside</li>
<li>Store as little as necessary in services, they are singletons</li>
</ul>
</section>
<section>
<h2>Example of Factory</h2>
<pre ng-non-bindable><code data-trim class="javascript">
angular.module('myApp', [])
.factory('myLogs', ['$http', function($http){
var myFact = function(){
//init script
this.reqUrl = '/includes/assets/scripts/rest/json.php';
this.logs = [];
this.query = {
func: 'get_logs',
args: []
}
}
myFact.prototype.getLogs = function(time){
this.query.args = [time];
$http.get(this.reqUrl, this.query)
.success(function(data){
this.logs = data;
}).error(function(){
this.logs = [];
console.log('there is a problem!!');
});
};
}])
.controller('myCtrl', ['$scope', 'myLogs', function($scope, myLogs){
$scope.fac = new myLogs();
}]);
</code></pre>
<pre ng-non-bindable><code data-trim class="html">
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="log in fac.logs" ng-bind="log.entry"></li>
</ul>
<button ng-click="fac.getLogs()">Update</button>
</div>
</code></pre>
<aside class="notes">
Notice
<ul>
<li>`.factory(name, ['req', function(req){}])</li>
<li>Creating an object for my factory and assigning it functions and variables</li>
<li>Query is self contained `this.query`</li>
<li>logs stay self contained `this.logs`</li>
<li>`myLogs` is fed into the controller as a requirement</li>
<li>a new myLogs is created, because this is a factory not a service</li>
<li>I wanted myLogs to be accessible so I placed it on the scope.</li>
<li>$http is another helper, this one is like the ajax method in jQuery</li>
<li>I am showing all the logs I want in almost no view or controller code.</li>
<li>My factory is fully testable</li>
</ul>
</aside>
</section>
</section>
<section id="roles">
<section>
<h1>Roles</h1>
<h2>How it is all supposed to work together</h2>
<aside class="notes">
to wrap it all up we have 4 main components, and now I will expain how they are to work
together to make our lives easier
</aside>
</section>
<section>
<h2>View</h2>
<ul>
<li>Declarative</li>
<li>Powerful</li>
<li>for designers</li>
</ul>
<br />
<br />
<h3>Try to keep it simple</h3>
<p>If it only deals in how things look it belongs in the view. <br />Ex: Simple Pagination</p>