Overview of Common Angular directives

Ng generate component example // Generate component example with template (short ng g c example) ng generate component example -it Ng generate module my-module // Generate a new module ng generate directive my-directive // generate a new directive ng generate pipe my-pipe // Ng generate route my-route ng generate class my-class // Generate a simple model classCopy the code

Install angular-CLI scaffolding. If NPM is slow, use Taobao Image

NPM install -g@angular /cli NPM I -g@angular /[email protected] // Install the specified version of Angular scaffolding // change the NPM source NPM configsetSuccessful NPM registry/https://registry.npm.taobao.org/verify configuration config get registry / / NPM https://registry.npmjs.org official sources / / CNPM installation, replacement of NPM CNPM source or use, a choice NPM install - g CNPM - registry=https://registry.npm.taobao.org / / note: Angular /[email protected] // Change the image source back to registry.npmjs.org; In order to install, the problem is speculated that taobao mirror source does not have this versionCopy the code

Create a project

Ng new myAngular // Create a project in git brash, The bootstrapping step ng new myAngular -- skpp-install // does not need to install dependencies ng new myangular-si // ng new myAngular --routing // Create a routed ng new myAngular --strict // using stricter typescript compilation optionsCopy the code

Component structure

// Import Component(Component decorator or Component annotation) from the Angular main module
import { Component } from '@angular/core';

// Metadata is declared as JSON in the decorator
@Component({
  // It specifies an element called 
      
       . This element is a placeholder in the index. HTML file
      
  // Why is this component associated with the entry index? Because the main module is bound to the appModule in the entry main.ts
  selector: 'app-root'.// Find the corresponding label in the template, create and insert the component instance
  templateUrl: './app.component.html'.// Component template
  styleUrls: ['./app.component.css'].// Component style
  // This property is either inline template or templateUrl. Template can be followed directly by the HTML string
  // Note that interpolation is used in template syntax (backquotes). You cannot insert values with ${}
  template: `<h1>{{title}}</h1>`   
})
// Component controller, where logic code is written
export class AppComponent {
  title = 'myAngular';
  // Constructors can be used to declare and initialize attributes
  // There is one particularly important point to remember in Angular: dependencies can only be injected through constructors
  constructor(){}}Copy the code

Modular structure

import { BrowserModule } from '@angular/platform-browser';
// Import NgModule from main module (module decorator or module annotation)
import { NgModule } from '@angular/core';
// Import components because modules provide the context in which components are compiled
import { AppComponent } from './app.component';

// The decorator declares metadata as JSON
@NgModule({
   // Combine module components and pipes
  declarations: [ AppComponent ],
  // Module dependencies
  imports: [ BrowserModule ],
  // Services provided by the module
  providers: [].// Specifies the host component, which occurs only in the root module
  bootstrap: [AppComponent]
})
export class AppModule {}Copy the code

Create component command

Ng generate component name ng g C component name // Abbreviation of the command above ng g C component name -it // Generate an inline template for testingCopy the code

Basic binding

// Value binding {{}} one-way binding module => view
// You can put variables and expressions in it, usually in HTML content, but it can also be used in attributes
msg:string = "Text";
bgClass:string = "bgRed";
<span>{{msg}}<span>
<div class="{{bgClass}}"></div>

// Attribute binding [] and {{}}
 public placeholder:string = "Dan"
 public index:number = 0
<input type="text" [value]="placeholder"></input>
<input type="text" value="{{placeholder}}"></input>
<input type="text" [value] ="{{placeholder}}"></input>
<input type="text" bind-value="placeholder"></input>
<input type="text" [attr.data-index] ="index"></input> // Custom property binding
// How to bind table clospan (two ways)
<tr><td [attr.colspan] ="2">Attribute mode binding</td></tr>
<tr><td [colSpan] ="2">Property</td></tr>
// Bind HTML content, which will automatically mask the contents of script tags to avoid security risks
htmlStr:string = "< h1 > title < / h1 > < script > location. The href ="www.baidu.com"</script>"
<div [innerHtml]="htmlStr"></div>

// The class binding in the property binding
public successClass:string = "text-success ..."
public hasError:Boolean = true;
public messageClasses: Object = {
    "text-success": false."text-danger": true
    }
public arrClass = ['aa'.'bb']
// Automatically add the class of the variable to the original class
<h2 class="aa" [class]="successClass"Title > </h2> // Binding values are string 

title </

h2> // The binding value is a string <h2 class="aa" [attr.class] ="successClass">The title</h2> // The binding value is a string <h2 [class.text-danger] = "hasError">The title</h2> // The binding value is Boolean <h2 [class] ="messageClasses">The title</h2> // Binding values are objects <h2 [class] ="{text-danger: true}">The title</h2> // Bind values are objects (essentially Boolean) <h2 [ngClass] ="{'text-danger': true}">The title</h2> // Bind values are objects (essentially Boolean) <h2 [class] ="['aa','bb']">The title</h2> // The binding values are arrays <h2 [class] ="arrClass">The title</h2> // The binding values are arrays // Style binding in attribute customization public styleStr:string= "background - colo: red; The font - size: 20 px ";public highlightColor:string = "orange"; public heightStr:string ="200px" public heightNum:number = 200; public titleStyles:Object = { color: "blue".fontStyle: "italic" } <h2 [style] = "styleStr"Title > </h2> /The binding value is a string

title </

h2> // The binding value is a string <h2 [style.height] = "heightStr">The title</h2> // The binding value is a string <h2 [style.height.px] = "heightNum">The title</h2> // The binding value is a number <h2 [style.color] = "hasError ? 'red':'green'">The title</h2> // The binding value is Boolean <h2 [style] = "titleStyles"> </h2> // Binding values are objects // loop instruction *ngFor arr:string[] = ['Joe'.'bill'.'Cathy']; trackByItems(index: number.item: Item): number { return item.id; } <div *ngFor="let item of arr; let i=index" (click)='choseThis(item,i)'{{item}} </div>//trackBy is usually used with long lists to reduce DOM substitutions and improve performance <div *ngFor="let item of items; trackBy: trackByItems"> ({{item.id}}) {{item.name}} </div> *ngIf style class ngSwitch isShow: Boolean = true; personState: number = 2; <p *ngIf="isShow">Command mode</p> // Frequent switching is not recommended. Frequent loading and removal have high performance consumption <p [style.display] ="isShow? 'block':'none'">Style pattern</p> // Frequently switch styles are recommended <p [class.hidden] ="isShow">The class model</p> // Conditional rendering that matches multiple cases, similar to Vue's V-if/V-else -if/ V-else <div [ngSwitch] = 'personState'> <div *ngSwitchCase="1">work</div> <div *ngSwitchCase="2">Have a meal</div> <div *ngSwitchDefault>Go to bed</div> </div> // Event binding () eventFunc(e){ // Get the event object, you can get the width and height of the element, set the style of the element, etc console.log(e); } <button (click) = "eventFunc($event)">Greet</button> /Button > <input (blur)="eventFunc($event)"> // Lost focus <input (keyup)="eventFunc($event)"> // Monitor keyboard input event <input (keyup.enter)="eventFunc($event)"> // Listen for a return to the keyboard to trigger an event Import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms'; Imports: [FormsModule] public name = "import "; <input [(ngModel)] ="name" type="text"> // Recommended <input bindon-change="name" type="text"> // optional // attribute binding + event binding = ngModel <input [value]="name" (input)="name=$event.target.value" > <input #phone placeholder="phone number"/> <button (click)="callPhone(call.value)">Call</button>Copy the code

Directives (attribute directives and structural directives)

// Attribute directives
// Function: provides a unified representation or behavior for elements
ng generate directive highlight // Create an instruction class file from the command line
// Here's an example: Add appHighlight to the template element, and the element's background becomes yellow and highlighted
import { Directive, ElementRef } from '@angular/core';
// Command decorator
@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow'; } } <p appHighlight>Highlight me! </p>// Directives can also respond to user events, such as a highlighted background when the mouse moves over an element, but not when it is removed
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  // We can define @input in directives to receive directives
  @Input('appHighlight') highlightColor: string;
  constructor(private el: ElementRef){}@HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.highlightColor || 'yellow');
  }
  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }
  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
  // You can also listen for events via elements
  this.el.nativeElement.addEventListener(click,() = > {
      this.el.nativeElement.style.height = 100px; })}// Pass values to attribute directives via attribute binding
<p [appHighlight]="'red'">Highlight me! </p>// Struct directive
*ngFor *ngIf ngSwitch
// Create a custom structural directive
// Example: implement a *ngElse directive with the opposite function *ngIf
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[ngElse]'})
export class UnlessDirective {
  private hasView = false;
  //TemplateRef retrieves the contents of 
      
  //ViewContainerRef to access the view container
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef){}@Input(a)set ngElse(condition: boolean) {
    if(! condition && !this.hasView) {
      this.viewContainer.createEmbeddedView(this.templateRef);
      this.hasView = true;
    } else if (condition && this.hasView) {
      this.viewContainer.clear();
      this.hasView = false; }}}// Use custom structural directives
<p *ngIf="isShow">IF</p>
// It can be optimized so that elements using ngElse can be unassigned and dynamically get the binding properties and values next to the element ngIf
<p *ngElse=! "" isShow">ELSE</p>
Copy the code

Routing system

// Route configuration item
//path: indicates the route path without/and wildcard **
Routes:Array<json> 
[{path: ' '.component : HomeComponent},  // No routing
{path: 'detail/:id'.component : DetailComponent},  // Route parameters are transmitted
{path:'* *'.component:Page404Component}]  // If you cannot find the route, go to the end of the 404 page

// Secondary routes, HTML placeholders, similar to slots and named slots
// secondary route output "aux"
routes=[
    {path:' '.component:center}, // Main route display
    {path:'auxVivwe'.component:auxViwe,outlet:'aux'}// Secondary route display
]
<router-outlet></router-outlet>
<router-outlet></router-oulet name='aux'>
// The main route is /, and the secondary route jumps to auxVivwe
<a [routerLink] ="['/',{outlet:'aux','auxVivwe'}]">1</a>

Router // A router object that can navigate to a specified route by calling its navigate() and navigateByUrl() methods
Router.navigate(Array<string>)  // Redirect the route to the specified route ['/']

//routerLink: string Labels the route navigation attribute
<a router-link="home"></a>
<a [routerLink] ="['home']"></a>

// The active object of the current route. Current route address and route parameters
ActivatedRouter
proto.queryParams[id] //get parameter object =? id=10
proto.params[id]      // Parameter = a/:id
proto.data[index].id  / / data data = [path: "', component: com, data: [{id: ABC}]]

// Redirect routes to redirectTo and pathMatch
//redirectTo:string Indicates the redirected route address
//pathMatch: Full Specifies whether to enable precise mode
{path:' '.redirectTo:'/home'.pathMatch:'full'}

// Route guard
CanActivate:fun // Handle routing to a route. The method returns true to allow the route to enter, false to block the route.
CanDeactivate:fun // Handle the current routing away condition call,
Resolve:fun // called before routing activates data
// Inject the route guard to the route
{path:'/home'.component:a,CanActivateExample: [and]}// Route data fetch function
object.subscribe(backFuntion) // Subscribe to data, call the callback method immediately if the object data changes
object.snapshot.object  // Obtain a data snapshot
Copy the code

Dependency injection, inversion of control

/ / providers
// Providers can be declared in @ngModuls() or @Component
providers: [{provider:'prod'.useClass:prod}]  // Direct instance

//useFactory:function Returns a class or value from a method. The factory method is called only once when the service needs to be provided
//deps:Array
      
        provides an intermediate provider for factory methods. It provides services that can be retrieved from @ngModule or @ Component
      
providers: [{provider:'prod'.useFactory:() = >{ return 1},deps:[loge]}]   // Provide factory method values
providers: [{provider:'prod'.useValue:false}]   // Provide a value

/ / injector
constructor(prod:prod){}
Copy the code

Piping (filter)

// Declare a function in the controller that filters the value and returns it, Tong vue writing / / can be more filters using The < div > {{value | myDate | json}} < / div > < div > The hero 's birthday is {{birthday | date: "MM/dd/yy"}} </div> <div> {{money | toMoney: '$'}} < / div > / / built-in pipe json / / will automatically object into a json string, Date :' YYYY-MM-DD '// Converts to the time format uppercase lowercase number:'2.2-2' // converts to the number format Ng g pipe /piper/mypiper/ng g pipe /piper/mypiper/ng g pipe /piper/mypiper Pipes (filters) generated from the command line are automatically declared globally; The parameters passed by the pipe are indicated after the ':' colonCopy the code

Safe navigation operators (useful)

// It is good practice to use safe navigation operators when using attributes of objects. // For multi-layer nested objects, use a? .b? .c? .d <p> product: {{product? .name}} < / p > < p > products: {{product?. Name?. FirstName}} < / p >Copy the code

communication

// Parent component communication

Parent component => child component
@Input() a:string; // Child components are defined in the controller
@Input(a)set b(b: string) { // Monitor the change of the input value, judge whether the input value meets the requirements, do not meet the requirements of the prompt user
    this._b = (b && b.trim()) || '<no name set>';
  }
  get b() :string { return this._b; }
@Input() c: function;
func(){ console.log("I'm the parent component method")}// The parent component passes down values or methods via property binding
<my-component  [a]='helloA' [b]='helloB' [c]="func"></my-component>

// Child component => parent component
// Child component, custom event and emitted<input type="button" (click)="vote(true)"> Exprot class son{// With EventEmitter @output () add = new EventEmitter<boolean>(); vote(agreed: boolean) { this.voted.emit(agreed); <div> <app-son (commented)=" oncute ($event)"> </app-son> </div> exprot class app{agreed = 0; onVoted(agreed: boolean) { agreed ? this.agreed++ : agreed--; ViewChild <childCompontent #child> </childComponent> @viewChild ('child') child1: Component this.child1. Attributes or methods / / through service to communication between the father and son components, can also use Localstorage/SessionStorage (h5 new local caching technology)Copy the code

Component lifecycle hooks

hook Timing and Use
ngOnChanges() Timing: Called when the value of the bound input property changes, the first call must occur before ngOnInit(). Purpose: Responds when Angular sets or resets input properties for a data binding. Note: This happens very frequently, so anything you do here can significantly affect performance.
ngOnInit() Timing: Called once after the first round of ngOnChanges() has completed. Purpose: Initializes a directive/component after Angular first displays the data binding and set directive/component input properties. A good place for the component to get initial data
ngDoCheck() Timing: Called immediately after ngOnChanges() on each change detection and ngOnInit() on the first change detection. Purpose: Detect and react to changes that Angular can’t or won’t detect itself. Note: this happens as frequently as ngOnChanges
ngAfterContentInit() Timing: Called only once after the first ngDoCheck(). Purpose: Called when Angular projects external content into a component view or directive view
ngAfterContentChecked() Timing: ngAfterContentInit() and called after each ngDoCheck(). Purpose: Called whenever Angular finishes checking for something projected into a component or directive.
ngAfterViewInit() Timing: Called after ngAfterContentChecked() the first time, only once. Purpose: Called after initializing the component view and its child views.
ngAfterViewChecked() Timing: ngAfterViewInit() and after each ngAfterContentChecked() call. Purpose: Called every time after component view and subview change detection.
ngOnDestroy() Timing: Called before Angular destroys the directive/component. Purpose: Called and cleaned every time Angular destroys a directive/component. Here, unsubscribe observables and detach event handlers to prevent memory leaks. Unsubscribe observables; Clear timer; Unregister all callbacks registered by the directive globally or in the application service.

Form processing ngFrom

// Common form base classesThe FormControl instance is used to track the value and validation status of a single FormControl. FormGroup is used to track the value and state of a form control group. FormArray is used to track the value and state of a form control array. ControlValueAccessor is used to create a bridge between Angular FormControl instances and native DOM elements.// Create a reactive form with automatic binding

// Step 1: import in app.module.ts
 imports: [ ReactiveFormsModule ]
 
// Step 2: Introduce FormControl in the component
import { FormControl } from '@angular/forms';
export class FavoriteColorComponent {
  name = new FormControl(' ');
}

// Step 3: Use it in a template
<label>Name:
   <input type="text" [formControl] ="name">
</label>

// Partially refresh the value of the form control
this.name.setValue('Joe');

// Create a control group
import { FormGroup, FormControl } from '@angular/forms';
profileForm = new FormGroup({
    firstName: new FormControl(' '),
    lastName: new FormControl(' ')}); <form [formGroup]="profileForm"> <label> First Name: <input type="text" formControlName="firstName"> </label> <label> Last Name: <input type="text" formControlName="lastName"> </label> </form> // Nested forms are similar to the above // patchValue() method is also used to replace the form model with any properties defined in the object. Refresh (local) enclosing profileForm. PatchValue ({firstName: Nancy, address: {street: '123 Drew street'}}); Import {Component} from '@angular/core'; import {Component} from '@angular/core'; @Component({ selector: 'app-template-favorite-color', template: `color: <input type="text" [(ngModel)]="favoriteColor">` }) export class FavoriteColorComponent { favoriteColor = ''; } // Use the FormBuilder service to generate controls // Step 1: Import the FormBuilder class. import { FormBuilder } from '@angular/forms'; // Step 2: Inject the FormBuilder service. Constructor (private fb: FormBuilder) {} step 3: Generate the form content. Export Class ProfileEditorComponent {// Each control name corresponds to an array of values, the first of which is its initial value. ProfileForm = this.fb.group({firstName: [",,Validators. Required],, lastName: ["], address: this.fb.group({ street: [''], city: [''], state: [''], zip: [''] }), }); }Copy the code

Access the server through HTTP

// Encapsulate the HTTP request
https://www.jb51.net/article/152056.htm / / reference document

// Step 1: Import HttpClientModule in the root module
import { HttpClientModule } from '@angular/common/http';
imports: [HttpClientModule]

// Step 2: Introduce HttpClient into the service and inject it through the constructor
import { HttpClient } from '@angular/common/http';
// Note: The HttpClient service uses observables for all work. You must import the RxJS observables and operators that appear in the sample code snippet
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';

constructor(private http: HttpClient){}getData() {
  // Call the get method, which returns an Observable, depending on the observe and responseType parameters you passed in
  return this.http.get('Requested address');
}

// Request options
options: { headers? : HttpHeaders | {[header:string] :string | string[]},
    The // option is used to specify the content of the response to return.observe? :'body' | 'events' | 'response', params? : HttpParams|{[param:string] :string | string[]}, reportProgress? :boolean.// The option specifies the format of the data to returnresponseType? :'arraybuffer'|'blob'|'json'|'text', withCredentials? :boolean,}// Asynchronous request
Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable
import { Observable } from 'rxjs/rx';
import { of } from 'rxjs/observable/of';
getHeroes(): Observable<Hero[]> {
    this.messageService.add('HeroService: fetched heroes');
    return of(HEROES);
}
Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable Observable
this.heroService.getHeroes() 
.subscribe(heroes= > this.refreshTree(heroes));

// Intercepts requests and responses
// Check the request string (check if it is empty)
private checkRequestUrl(requestUrl: string) :boolean {
    if(! requestUrl ||' ' == requestUrl.trim() || null == requestUrl) {
      console.error('Request URL is empty, please check');
      return false;
    }
    return true;
}
// Check the POST request parameter (check if it is null)
 private checkParams(data: any) :boolean {
    // General empty check
    if(! postData ||null == postData) {
      console.error('Requested data is empty, please check');
      return false;
    }
    return true;
}

// How do I get the current routing address
//Location and PlatformLocation can both get the current routing address
 private planform: PlatformLocation,
 private location: Location,
 this.profileMenu['href'] = '/profile/setting';
// Remove '/' from route
const refreshUrl = this.planform.pathname.split('/'.2) [1];
this.displayChange = refreshUrl === 'page-index';
Copy the code

Start the presents

NPM start ng serve --open // Start the project and open the browser ng serve -o // short for the previous command ng serve --port // Specify the port on which the program runsCopy the code