- Directives are decorated classes
- A directive is a decorator -- @Directive()
- Angular templates are dynamic. When Angular renders them, it transforms the DOM according to the instructions given by directives.
- A component is also a type of directive.
Directives have metadata associated with them: selectors, provider, input, output, etc.
@Input & @Output
- Two directives for sharing data between the parent and the child components
@Input
@Input marks a class field as an input property and supplies configuration metadata. The input property is bound to a DOM property in the template. During change detection, Angular automatically updates the data property with the DOM property's value.
In parent component:
export class AppComponent {
parentCounter = 10;
}
**此处declare本地变量parentCounter
In parent component template:
<child-component [counterValue] = "parentCounter"></child-component>
**此处用counterValue这个attribute和property-binding把parentCounter导出
In child component class:
@Input() counterValue = 0;
** 此处将counterValue对象mark为@input property导入
In child component HTML:
<p>
Today's count: {{counterValue}}
</p>
** 此处data-binding把child component的counterValue值展示出来
@Output
@Output marks a class field as an output property and supplies configuration metadata. The DOM property bound to the output property is automatically updated during change detection.
- Child --> Parent 单向传参
In child component class:
@Output() newItemEvent = new EventEmitter<string>();
** 此处创建newItemEvent为@Output property导出
addNewItem(value: any) {
console.log("in child component: addNewItem()");
console.log(value);
this.newItem = value;
this.newItemEvent.emit(value);
}
** 此处创建addNewItem方法在有新值的时候用event发射出去
In child component HTML:
<!-- HTML <input> for a new item -->
<input type="text" id="item-input" #item> <!-- template reference variable -->
<!-- a <button> with a click event binding.
On clicking event addNewItem in component gets called.
pass value from the input box to the component -->
<button type="button" (click)="addNewItem(item.value)">Add to parent's list</button>
** 此处event-binding把child component的addNewItem方法bind到button上
In parent component:
export class AppComponent {
title = 'my-angular-app';
today_item = "cream puff";
items = [this.today_item];
addItem(item: string){
this.items.push(item);
}
}
**此处addItem本地方法push新item至array
In parent component template:
<child-component [counterValue] = "parentCounter" (newItemEvent)="addItem($event)"></child-component>
**此处event binding将addItem本地方法绑定至child的output event,每次有新值都会call这个方法
Attribute Directives
Listen to and modify the behavior of existing HTML elements -- attributes, properties, and components.
NgClass
Add and remove multiple HTML element classes at the same time.
Example 1
<!-- toggle the "special" class on/off with a property -->
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
- isSpecial -- a boolean variable in the .ts class
- isSpecial is true -- apply 'special' class
- isSpecial is flase -- apply nothing
Example 2
currentClasses: Record<string, boolean> = {};
/* . . . */
setCurrentClasses() {
// CSS classes: added/removed per current state of component properties
this.currentClasses = {
saveable: this.canSave,
modified: !this.isUnchanged,
special: this.isSpecial
};
}
- In .ts class
- setCurrentClasses: a method used to change the classes applied to the element
- involked when the toggle button is clicked.
- currentClasses: an object of HTML classes that is applied to the element
- setCurrentClasses: a method used to change the classes applied to the element
<div [ngClass]="currentClasses">This div is initially saveable, unchanged,
and special.</div>
- In HTML
- currentClasses object is attached to the div
- When the boolean value of that class is set to true, the class is applied
- e.g savable is applied when canSave is true
NgModel
Used for two-way data binding, see Angular -- Data Binding
Structural directives
Used for manipulating HTML layout --
- Add or Remove DOM elements
NgIf
<app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>
- app-item-detail is applied when ngIf evaluates to true, hidden when ngIf evaluates to false
NgFor
<div *ngFor="let item of items; let i=index" *ngIf="isSpecial">{{item.name}} -- {{i}}</div>
- Loop through each item in items array in .ts class.
- Each item has a div with its name in it.
- i is the 0-based index of the item, a property provided by the ngFor directive.
- Only show the item div when isSpecial condition is true.
NgSwitch
NgSwitch
displays one element from among several possible elements, based on a switch condition. Angular puts only the selected element into the DOM.
<div [ngSwitch]="currentItem.feature">
<app-stout-item *ngSwitchCase="'stout'" [item]="currentItem"></app-stout-item>
<app-device-item *ngSwitchCase="'slim'" [item]="currentItem"></app-device-item>
<app-lost-item *ngSwitchCase="'vintage'" [item]="currentItem"></app-lost-item>
<app-best-item *ngSwitchCase="'bright'" [item]="currentItem"></app-best-item>
<!-- . . . -->
<app-unknown-item *ngSwitchDefault [item]="currentItem"></app-unknown-item>
</div>
- [ngSwitch] is binded to a value in the .ts class, that is the value that is switched on.
- Each possible element has a *ngSwitchCase directive that is selected when the [ngSwitch] value matches the directive value.