* ts template-syntax.jade without docregion tags * update guide/template-syntax for dart and ts * clarify style property naming in Dart
		
			
				
	
	
		
			235 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
// #docregion
 | 
						|
import 'dart:convert';
 | 
						|
import 'dart:html';
 | 
						|
 | 
						|
import 'package:angular2/core.dart';
 | 
						|
import 'package:angular2/common.dart';
 | 
						|
 | 
						|
import 'hero.dart';
 | 
						|
import 'hero_detail_component.dart';
 | 
						|
import 'my_click_directive.dart';
 | 
						|
 | 
						|
enum Color { red, green, blue }
 | 
						|
 | 
						|
@Component(
 | 
						|
    selector: 'my-app',
 | 
						|
    templateUrl: 'app_component.html',
 | 
						|
    directives: const [
 | 
						|
      HeroDetailComponent,
 | 
						|
      BigHeroDetailComponent,
 | 
						|
      MyClickDirective,
 | 
						|
      MyClickDirective2
 | 
						|
    ])
 | 
						|
class AppComponent implements OnInit, AfterViewInit {
 | 
						|
  @override
 | 
						|
  void ngOnInit() {
 | 
						|
    refreshHeroes();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void ngAfterViewInit() {
 | 
						|
    _detectNgForTrackByEffects();
 | 
						|
  }
 | 
						|
 | 
						|
  String heroName;
 | 
						|
  String help;
 | 
						|
  String actionName = 'Go for it';
 | 
						|
  String badCurly = 'bad curly';
 | 
						|
  String classes = 'special';
 | 
						|
  bool canSave = true;
 | 
						|
  bool isActive = false;
 | 
						|
  bool isSpecial = true;
 | 
						|
  bool isUnchanged = true;
 | 
						|
  bool isSelected = false;
 | 
						|
  final Color colorRed = Color.red;
 | 
						|
  Color color = Color.red;
 | 
						|
  var colorEnum = Color;
 | 
						|
 | 
						|
  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
 | 
						|
 | 
						|
  final Hero nullHero = null;
 | 
						|
  Map product = {'name': 'frimfram', 'price': 42};
 | 
						|
  FormElement form;
 | 
						|
  String clicked = '';
 | 
						|
  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';
 | 
						|
 | 
						|
  // 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';
 | 
						|
 | 
						|
  void alerter(String msg) {
 | 
						|
    window.alert(msg);
 | 
						|
  }
 | 
						|
 | 
						|
  void callFax(String value) {
 | 
						|
    alerter('Faxing $value ...');
 | 
						|
  }
 | 
						|
 | 
						|
  void callPhone(String value) {
 | 
						|
    alerter('Calling $value ...');
 | 
						|
  }
 | 
						|
 | 
						|
  void colorToggle() {
 | 
						|
    color = (color == Color.red) ? Color.blue : Color.red;
 | 
						|
  }
 | 
						|
 | 
						|
  int getVal() => val;
 | 
						|
 | 
						|
  void onCancel(UIEvent event) {
 | 
						|
    HtmlElement el = event?.target;
 | 
						|
    var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : '';
 | 
						|
    alerter('Canceled. $evtMsg');
 | 
						|
  }
 | 
						|
 | 
						|
  void onClickMe(UIEvent event) {
 | 
						|
    HtmlElement el = event?.target;
 | 
						|
    var evtMsg = event != null ? 'Event target class is ${el.className}.' : '';
 | 
						|
    alerter('Click me. $evtMsg');
 | 
						|
  }
 | 
						|
 | 
						|
  void deleteHero([Hero hero]) {
 | 
						|
    alerter('Deleted hero: ${hero?.firstName}');
 | 
						|
  }
 | 
						|
 | 
						|
  bool onSave([UIEvent event = null]) {
 | 
						|
    HtmlElement el = event?.target;
 | 
						|
    var evtMsg =
 | 
						|
        event != null ? ' Event target is ${el.innerHtml}.' : '';
 | 
						|
    alerter('Saved. $evtMsg');
 | 
						|
    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) {
 | 
						|
    var showStyles = setStyles();
 | 
						|
    return JSON.encode(showStyles);
 | 
						|
  }
 | 
						|
 | 
						|
  Map<String, bool> _previousClasses = {};
 | 
						|
  // #docregion setClasses
 | 
						|
  Map<String, bool> setClasses() {
 | 
						|
    final classes = {
 | 
						|
      'saveable': canSave, // true
 | 
						|
      'modified': !isUnchanged, // false
 | 
						|
      'special': isSpecial // true
 | 
						|
    };
 | 
						|
    // #docregion setClasses
 | 
						|
    // compensate for DevMode (sigh)
 | 
						|
    if (JSON.encode(_previousClasses) ==
 | 
						|
        JSON.encode(classes)) return _previousClasses;
 | 
						|
    _previousClasses = classes;
 | 
						|
    // #enddocregion setClasses
 | 
						|
    return classes;
 | 
						|
  }
 | 
						|
  // #enddocregion setClasses
 | 
						|
 | 
						|
  // #docregion setStyles
 | 
						|
  Map setStyles() {
 | 
						|
    return {
 | 
						|
      'font-style': canSave ? 'italic' : 'normal', // italic
 | 
						|
      'font-weight': !isUnchanged ? 'bold' : 'normal', // normal
 | 
						|
      'font-size': isSpecial ? '24px' : '8px' // 24px
 | 
						|
    };
 | 
						|
  }
 | 
						|
  // #enddocregion setStyles
 | 
						|
 | 
						|
  String title = 'Template Syntax';
 | 
						|
  String toeChoice;
 | 
						|
  String toeChooser(Element picker) {
 | 
						|
    List<Element> choices = picker.children;
 | 
						|
    for (var i = 0; i < choices.length; i++) {
 | 
						|
      var choice = choices[i] as CheckboxInputElement;
 | 
						|
      if (choice.checked) {
 | 
						|
        toeChoice = choice.value;
 | 
						|
        return toeChoice;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  // #docregion trackByHeroes
 | 
						|
  int trackByHeroes(int index, Hero hero) => hero.id;
 | 
						|
  // #enddocregion trackByHeroes
 | 
						|
 | 
						|
  // #docregion trackById
 | 
						|
  int trackById(int index, dynamic item) => item.id;
 | 
						|
  // #enddocregion trackById
 | 
						|
 | 
						|
  int val = 2;
 | 
						|
 | 
						|
  //////// Detect effects of NgForTrackBy ///////////////
 | 
						|
  int heroesNoTrackByChangeCount = 0;
 | 
						|
  int heroesWithTrackByChangeCount = 0;
 | 
						|
 | 
						|
  @ViewChildren('noTrackBy') QueryList<ElementRef> childrenNoTrackBy;
 | 
						|
  @ViewChildren('withTrackBy') QueryList<ElementRef> childrenWithTrackBy;
 | 
						|
 | 
						|
  void _detectNgForTrackByEffects() {
 | 
						|
    /// Converts [viewChildren] to a list of [Element].
 | 
						|
    List<Element> _extractChildren(QueryList<ElementRef> viewChildren) =>
 | 
						|
        viewChildren.toList()[0].nativeElement.children.toList() as List<Element>;
 | 
						|
 | 
						|
    {
 | 
						|
      // 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++;
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
  }
 | 
						|
  ///////////////////
 | 
						|
}
 |