Angular -- Directives

连时铭
2023-12-01
  • 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.

  • Parent --> Child 单向传参
  • To watch for changes on an @Input() property, use OnChanges

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
<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.
 类似资料: