Structural directives: ngIf - lordoftheflies/angular-essential-training GitHub Wiki
Angular has two types of directives, structural and attribute. Let's take a look at structural directives first. A structural directive is designed to alter the DOM layout by adding or removing DOM elements. Let's start with the Angular directive ngIf. ngIf will conditionally render the DOM element that the directive is on. In the media-item.component.html file we have some markup to display the data from the media item object. The watched on property on a media item may be empty so we want the DOM to not contain the element that has the watched on in the case that the media item doesn't have a watched on value. The ngIf structural directive works for this, so we want to put the ngIf directive on the container element for the value. Structural directives are applied to normal DOM elements using an asterisk template syntax. So on the element we need to put asterisk ngIf and set that equal to a statement that will evaluate to true or false. In this case, we want to see if mediaItem.watchedon has a value, so we can put mediaItem.watchedon in the expression. And if watched on has a value, it will evaluate to truthy. Let's see what the ngIf does. Over in the browser when we inspect the media item we can see that the watched on container is in the DOM because we have a watched on value, but what happens when watched on is null? Let's flip over to the app.component.ts file and set the watched on property to null. And then back in the browser, if we inspect the DOM we can see that the container element is not in the tree. The ngIf structural directive changes the DOM for us, that's what makes it a structural directive. Before we can check out another common structural directive let's talk about that asterisk syntax. The asterisk is what is referred to as syntactic sugar. Syntactic sugar is a shorthand pattern for writing something that the platform will interpret and convert to the actual syntax. Structural directors work with ng-template elements to modify the DOM. A structural directive placed on an element named ng-template will handle either rendering or not rendering the inner children of that template element in place of the ng-template element itself. So back in the code we can actually rework the way we use ngIf here, removing the asterisk ngIf directive binding and add an ng-template element around the container element and put the ngIf directive on that ng-template element using the bracket syntax around ngIf and having that equal to the same statement. Angular knows that the ng-template element is not something that you want added to the DOM, so even in the case where the ngIf evaluates to true we are only left with the contents from within the ng template element. The asterisk syntax allows you to skip having to write the ng-template tag and simply put the structural directive directly on the element that is the contents of the ng-template. Note that both ways work the same, the named element ng-template is something that never makes it to the DOM, it's handled by Angular during its component template parsing. But there are times where using the ng-template element for your ngIf is handy, like when you want to conditionally render multiple sibling elements based on the same conditional statement and not introduce another DOM element to do so.