Saturday, June 25, 2016

Learning Angular 2: Tour of Heroes Tutorial, Lesson 3

Building on the lesson 2 coding exercises in the Tour of Heroes tutorial I covered in my last post, the next lesson involves displaying a list of Hero objects.

The "*ngFor" syntax is obviously a departure from the "ng-repeat" syntax of Angular 1.  Less obvious is the fact that now the iteration syntax includes a standard variable declaration ("let").  Leave it off and you get a page-breaking error.  In Angular 1 you could have gotten away with just "hero in heroes".

I glanced at some of the docs for ngFor and saw a number of ideas inherited from ng-repeat:  the ability to grab the index value, the ability to apply certain styles based on an even or odd index value, etc.  But I didn't see any syntax examples for using ngFor to iterate over object literal properties or Maps, something I would do from time-to-time in Angular 1 but would always forget the iteration syntax for.
Curious enough to get sidetracked, I did some searching and learned that currently ngFor doesn't support looping over key/value pair constructs:

https://github.com/angular/angular/issues/2246

...but it sounds like the notion of providing a pipe in the Angular 2 codebase to allow for that is still on the table (a pipe being a function for transforming data values).  And there are a few blog posts out there about writing your own pipe to achieve that functionality.  Something to look into further down the line.

I like the idea of having a "styles" property on a component.  I can see where keeping project-agnostic styles within the component would make it easier to use in multiple projects.

In my previous post I commented on how the initial property assignments in AppComponent (like "title") were untyped.  The "selectedHero" property introduced in this lesson does not have an initial value but is typed as a variable of type Hero.
The new "*ngIf" directive seems straightforward enough, and like the "ng-if" of Angular 1 it can process a compound boolean expression:


<div *ngIf="selectedHero && 1 == 1">

...but seeing it made me curious if the Angular 1 core directives "ng-show" and "ng-hide" also existed in Angular 2 (in my work projects we tended to use those rather than "ng-if" in many places).  Looks like the answer to that is no.  The developer guide page on structural directives like ngIf, ngFor, and ngSwitch makes the point that you're often (though not always) better off using ngIf to destroy the DOM element not in use, thereby removing any of the binding listeners that go with it.

I noticed on that same guide page that the ngSwitch directive was NOT preceded by an asterisk (*) like ngFor and ngIf..and at first glance it seemed like the child ngSwitchWhen directives were not either, until I sat back and realized that in that code example the <template> element the asterisk implies for these directives was "spelled out" in the example.

However, that DOES NOT mean I can do this:


<template ngIf="selectedHero">...</template>

...without the "*", it errors, and with the "*" the browser doesn't know how to render a <template> tag so it isn't displayed....which makes me wonder if the <template> ngSwitchWhen example works....(Chuckle), it does, but I get console messages saying that "ngSwitchWhen is deprecated; use ngSwitchCase instead".  I see there's a pull request to update the docs regarding this change (https://github.com/angular/angular.io/pull/1710).

The last coding step of the lesson:


[class.selected]="hero === selectedHero"

...is technically a class binding, not a property binding as stated in the lesson. And it's limited to assigning one class based on the evaluation of the expression, whereas the ngClass directive supports setting multiple classes.

No comments:

Post a Comment