| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | // #docregion
 | 
					
						
							|  |  |  | import 'dart:convert'; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  | import 'dart:html'; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 16:03:53 -07:00
										 |  |  | import 'package:angular2/core.dart'; | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  | import 'package:angular2/common.dart'; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  | import 'hero.dart'; | 
					
						
							|  |  |  | import 'hero_detail_component.dart'; | 
					
						
							| 
									
										
										
										
											2016-11-14 08:34:10 -08:00
										 |  |  | import 'click_directive.dart'; | 
					
						
							|  |  |  | import 'sizer_component.dart'; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | enum Color { red, green, blue } | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | @Component( | 
					
						
							|  |  |  |     selector: 'my-app', | 
					
						
							|  |  |  |     templateUrl: 'app_component.html', | 
					
						
							|  |  |  |     directives: const [ | 
					
						
							|  |  |  |       HeroDetailComponent, | 
					
						
							|  |  |  |       BigHeroDetailComponent, | 
					
						
							|  |  |  |       MyClickDirective, | 
					
						
							| 
									
										
										
										
											2016-11-14 08:34:10 -08:00
										 |  |  |       MyClickDirective2, | 
					
						
							|  |  |  |       MySizerComponent | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |     ]) | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | class AppComponent implements OnInit, AfterViewInit { | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void ngOnInit() { | 
					
						
							|  |  |  |     refreshHeroes(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void ngAfterViewInit() { | 
					
						
							|  |  |  |     _detectNgForTrackByEffects(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   String heroName; | 
					
						
							|  |  |  |   String help; | 
					
						
							|  |  |  |   String actionName = 'Go for it'; | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |   String badCurly = 'bad curly'; | 
					
						
							| 
									
										
										
										
											2016-02-17 10:59:14 -08:00
										 |  |  |   String classes = 'special'; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   bool canSave = true; | 
					
						
							|  |  |  |   bool isActive = false; | 
					
						
							|  |  |  |   bool isSpecial = true; | 
					
						
							|  |  |  |   bool isUnchanged = true; | 
					
						
							|  |  |  |   bool isSelected = false; | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  |   final Color colorRed = Color.red; | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   Color color = Color.red; | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  |   var colorEnum = Color; | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   List<Hero> heroes; | 
					
						
							|  |  |  |   Hero currentHero; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // #docregion refresh-heroes
 | 
					
						
							|  |  |  |   /// Updates [this.heroes] with fresh set of cloned heroes.
 | 
					
						
							|  |  |  |   void refreshHeroes() { | 
					
						
							|  |  |  |     heroes = mockHeroes.map((hero) => hero.clone()).toList(); | 
					
						
							|  |  |  |     currentHero = heroes[0]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // #enddocregion refresh-heroes
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |   final Hero nullHero = null; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   Map product = {'name': 'frimfram', 'price': 42}; | 
					
						
							|  |  |  |   FormElement form; | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  |   String clicked = ''; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |   String clickMessage = ''; | 
					
						
							|  |  |  |   String clickMessage2 = ''; | 
					
						
							|  |  |  |   final String iconUrl = 'assets/images/ng-logo.png'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
 | 
					
						
							|  |  |  |   // Public Domain terms of use: http://www.wpclipart.com/terms.html
 | 
					
						
							|  |  |  |   final String heroImageUrl = 'assets/images/hero.png'; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |   // villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png'
 | 
					
						
							|  |  |  |   // Public Domain terms of use http://www.clker.com/disclaimer.html
 | 
					
						
							|  |  |  |   final String villainImageUrl = 'assets/images/villain.png'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   void alerter(String msg) { | 
					
						
							|  |  |  |     window.alert(msg); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   void callFax(String value) { | 
					
						
							|  |  |  |     alerter('Faxing $value ...'); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   void callPhone(String value) { | 
					
						
							|  |  |  |     alerter('Calling $value ...'); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void colorToggle() { | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |     color = (color == Color.red) ? Color.blue : Color.red; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |   int getVal() => val; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  |   void onCancel(UIEvent event) { | 
					
						
							|  |  |  |     HtmlElement el = event?.target; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |     var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : ''; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |     alerter('Canceled. $evtMsg'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  |   void onClickMe(UIEvent event) { | 
					
						
							|  |  |  |     HtmlElement el = event?.target; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |     var evtMsg = event != null ? 'Event target class is ${el.className}.' : ''; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |     alerter('Click me. $evtMsg'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   void deleteHero([Hero hero]) { | 
					
						
							|  |  |  |     alerter('Deleted hero: ${hero?.firstName}'); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-02-17 10:59:14 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-25 15:09:45 -07:00
										 |  |  |   bool onSave([UIEvent event = null]) { | 
					
						
							|  |  |  |     HtmlElement el = event?.target; | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |     var evtMsg = event != null ? ' Event target is ${el.innerHtml}.' : ''; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |     alerter('Saved. $evtMsg'); | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onSubmit(NgForm form) { | 
					
						
							|  |  |  |     var evtMsg = form.valid | 
					
						
							|  |  |  |         ? ' Form value is ${JSON.encode(form.value)}' | 
					
						
							|  |  |  |         : ' Form is invalid'; | 
					
						
							|  |  |  |     alerter('Form submitted. $evtMsg'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void setUpperCaseFirstName(String firstName) { | 
					
						
							|  |  |  |     currentHero.firstName = firstName.toUpperCase(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String getStyles(Element el) { | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |     final style = el.style; | 
					
						
							|  |  |  |     final Map styles = <String, String>{}; | 
					
						
							|  |  |  |     for (var i = 0; i < style.length; i++) { | 
					
						
							|  |  |  |       styles[style.item(i)] = style.getPropertyValue(style.item(i)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return JSON.encode(styles); | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   Map<String, bool> _previousClasses = {}; | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |   // #docregion setClasses
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   Map<String, bool> setClasses() { | 
					
						
							|  |  |  |     final classes = { | 
					
						
							|  |  |  |       'saveable': canSave, // true
 | 
					
						
							|  |  |  |       'modified': !isUnchanged, // false
 | 
					
						
							|  |  |  |       'special': isSpecial // true
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     // #docregion setClasses
 | 
					
						
							|  |  |  |     // compensate for DevMode (sigh)
 | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |     if (JSON.encode(_previousClasses) == JSON.encode(classes)) | 
					
						
							|  |  |  |       return _previousClasses; | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |     _previousClasses = classes; | 
					
						
							|  |  |  |     // #enddocregion setClasses
 | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |     return classes; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // #enddocregion setClasses
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   // #docregion setStyles
 | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |   Map<String, String> setStyles() { | 
					
						
							|  |  |  |     return <String, String>{ | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |       'font-style': canSave ? 'italic' : 'normal', // italic
 | 
					
						
							|  |  |  |       'font-weight': !isUnchanged ? 'bold' : 'normal', // normal
 | 
					
						
							|  |  |  |       'font-size': isSpecial ? '24px' : '8px' // 24px
 | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   } | 
					
						
							|  |  |  |   // #enddocregion setStyles
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |   // #docregion NgStyle
 | 
					
						
							|  |  |  |   bool isItalic = false; | 
					
						
							|  |  |  |   bool isBold = false; | 
					
						
							|  |  |  |   String fontSize = 'large'; | 
					
						
							| 
									
										
										
										
											2016-11-14 08:34:10 -08:00
										 |  |  |   String fontSizePx = '14'; | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Map<String, String> setStyle() { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       'font-style': isItalic ? 'italic' : 'normal', | 
					
						
							|  |  |  |       'font-weight': isBold ? 'bold' : 'normal', | 
					
						
							|  |  |  |       'font-size': fontSize | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // #enddocregion NgStyle
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-06 17:18:26 -08:00
										 |  |  |   String title = 'Template Syntax'; | 
					
						
							| 
									
										
										
										
											2016-08-16 05:43:29 -07:00
										 |  |  |   // #docregion evil-title
 | 
					
						
							|  |  |  |   String evilTitle = 'Template <script>alert("evil never sleeps")</script>Syntax'; | 
					
						
							|  |  |  |   // #enddocregion evil-title
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-06 17:18:26 -08:00
										 |  |  |   String toeChoice; | 
					
						
							| 
									
										
										
										
											2016-08-16 05:43:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   String toeChooser(Element picker) { | 
					
						
							|  |  |  |     List<Element> choices = picker.children; | 
					
						
							|  |  |  |     for (var i = 0; i < choices.length; i++) { | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |       var choice = choices[i] as CheckboxInputElement; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |       if (choice.checked) { | 
					
						
							| 
									
										
										
										
											2016-01-26 15:48:03 -08:00
										 |  |  |         toeChoice = choice.value; | 
					
						
							|  |  |  |         return toeChoice; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return null; | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-02-06 17:18:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // #docregion trackByHeroes
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   int trackByHeroes(int index, Hero hero) => hero.id; | 
					
						
							| 
									
										
										
										
											2016-02-06 17:18:26 -08:00
										 |  |  |   // #enddocregion trackByHeroes
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // #docregion trackById
 | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  |   int trackById(int index, dynamic item) => item.id; | 
					
						
							| 
									
										
										
										
											2016-02-06 17:18:26 -08:00
										 |  |  |   // #enddocregion trackById
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int val = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //////// Detect effects of NgForTrackBy ///////////////
 | 
					
						
							|  |  |  |   int heroesNoTrackByChangeCount = 0; | 
					
						
							|  |  |  |   int heroesWithTrackByChangeCount = 0; | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |   @ViewChildren('noTrackBy') | 
					
						
							|  |  |  |   QueryList<ElementRef> childrenNoTrackBy; | 
					
						
							|  |  |  |   @ViewChildren('withTrackBy') | 
					
						
							|  |  |  |   QueryList<ElementRef> childrenWithTrackBy; | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void _detectNgForTrackByEffects() { | 
					
						
							|  |  |  |     /// Converts [viewChildren] to a list of [Element].
 | 
					
						
							|  |  |  |     List<Element> _extractChildren(QueryList<ElementRef> viewChildren) => | 
					
						
							| 
									
										
										
										
											2016-08-11 11:47:59 -07:00
										 |  |  |         viewChildren.toList()[0].nativeElement.children.toList() | 
					
						
							|  |  |  |         as List<Element>; | 
					
						
							| 
									
										
										
										
											2016-02-23 14:33:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // Updates 'without TrackBy' statistics.
 | 
					
						
							|  |  |  |       List<Element> _oldNoTrackBy = _extractChildren(this.childrenNoTrackBy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.childrenNoTrackBy.changes.listen((Iterable<ElementRef> changes) { | 
					
						
							|  |  |  |         final newNoTrackBy = _extractChildren(changes); | 
					
						
							|  |  |  |         final isSame = newNoTrackBy.fold(true, (bool isSame, Element elt) { | 
					
						
							|  |  |  |           return isSame && _oldNoTrackBy.contains(elt); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!isSame) { | 
					
						
							|  |  |  |           _oldNoTrackBy = newNoTrackBy; | 
					
						
							|  |  |  |           this.heroesNoTrackByChangeCount++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // Updates 'with TrackBy' statistics.
 | 
					
						
							|  |  |  |       List<Element> _oldWithTrackBy = | 
					
						
							|  |  |  |           _extractChildren(this.childrenWithTrackBy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.childrenWithTrackBy.changes.listen((Iterable<ElementRef> changes) { | 
					
						
							|  |  |  |         final newWithTrackBy = _extractChildren(changes); | 
					
						
							|  |  |  |         final isSame = newWithTrackBy.fold(true, (bool isSame, Element elt) { | 
					
						
							|  |  |  |           return isSame && _oldWithTrackBy.contains(elt); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!isSame) { | 
					
						
							|  |  |  |           _oldWithTrackBy = newWithTrackBy; | 
					
						
							|  |  |  |           this.heroesWithTrackByChangeCount++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-02-06 17:18:26 -08:00
										 |  |  |   } | 
					
						
							|  |  |  |   ///////////////////
 | 
					
						
							| 
									
										
										
										
											2015-11-15 23:38:50 -07:00
										 |  |  | } |