Angular Fundamentals Summary
- Create project:
ng new projectName - Start project:
ng serve --open - Create component:
ng g c directory/componentName - Create module:
ng g m directory/moduleName - Create service:
ng g s directory/serviceName
- Angular Project Directory Analysis
- Initial Angular Modules
2.1 Contents Included in a Module:
- Components
- Services
- Directives
- Note: The above three must be configured in the module before they can be used!
2.2 Example
- Use
ng g m todo-listto create the todo-list module - Use
ng g c todo-list/componentNameto create two components in that directory
2.3 Exporting and Importing Modules
- Directives
3.1 Interpolation {{ }}
3.2 Property Binding
-
[propertyName] = "data"or -
propertyName = "{{ data }}"or -
`propertyName = "string"
-
With [ ], or without [ ], using {{ }}, indicates that data is a variable
-
Without [ ], indicates that string is a string
3.3 Event Binding
- Regular event binding:
(click) = "handleClick()" - Event binding with event object:
(click) = "handleClick($event)", template usage as follows:
handleClick(e){
console.log(e)
e.preventDefault()//prevent default behavior
}
3.4 Two-way Data Binding
[(ngModel)] = "modelData"- Note: The [(ngModel)] directive is in the Angular FormsModule module, which needs to be imported into the module before use
3.5 [ngClass]
- Operate a class name
//html
<p [class.redColor] = "isRed">111</p>
//ts
isRed = true;
//css
.redColor{
color:red;
}
- Operate multiple class names
//html
<p [ngClass] = "classObj">ceshi</p>
//ts
classObj = {
redColor: true,
myFontSize: false
}
css
.color{
color:red;
}
.myFontSize{
font-size:12px;
}
3.6 [ngStyle]
- Operate one style
//html
<p [style.color] = "colorName">111</P>
//ts
colorName = 'red';
- Operate multiple styles
//html
<p [ngStyle] = "styleObj">111</P>
//ts
styleObj = {
color: 'red',
fontSize:'12px'
}
3.7 *ngIf
- HTML:
<h1 *ngIf = "isShow">111</h1> - TS:
isShow = false;
3.8 *ngFor
- Iterate over a normal array:
<i *ngFor = "let item of Arrys; let i = index; let isOdd = odd"> {{ item }}--{{ i }}--{{ isOdd ? 奇 : 偶 }} </i> - Iterate over an object array: benefit, improve rendering performance.
//html add trackBy means tracking self, so when part of the object list changes, only the changed data is re-rendered
<i *ngFor="let item of nameList; trackBy: trackById"></i>
//ts
nameList = [
{ id: 1, name: 'xiaoming' },
{ id: 2, name: 'xiaohuang' },
{ id: 3, name: 'xiaolan' }
]
//add this method
trackById(i:number,item:any){
return item.id
}
- Component Nesting
//Parent component uses child component, need to import and declare in the parent module.ts file:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ChildComponent } from './child/child.component'; //import
@NgModule({
declarations: [
AppComponent,
ChildComponent //declare
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
- Component Communication
5.1 Parent to Child
//Parent component
//html
<!-- Parent component uses child component and passes data to it -->
<app-child [myProp] = 'prop'></app-child>
//ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
prop = 'fatherData'
}
//Child component
//ts
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.less']
})
export class ChildComponent implements OnInit {
constructor() { }
// Receive data passed from parent component
// Need to use Input to declare, note that Input must be imported above
@Input()
myProp:any
ngOnInit(): void {
}
}
5.2 Child to Parent
//Child component
import { Component, Output,EventEmitter, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.less']
})
export class ChildComponent implements OnInit {
constructor() { }
// Data to transmit
childData = 'someData'
// 1. Child component creates a custom EventEmitter event
@Output()
put = new EventEmitter()
// 3. Child component triggers the custom event, thus triggering the parent component's receiving event
handleClick(){
this.put.emit(this.childData) // parameter is the data to be transmitted
}
ngOnInit(): void {
}
}
//Parent component
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
// 2. In the parent component, use the child component's custom event and bind the receiving function
template: `<app-child (put)="get($event)"></app-child>`,
styleUrls: ['./app.component.less']
})
export class AppComponent {
mydata:any
// 4. Receiving data processing function
get(data:any){
this.mydata = data
}
}
- Services
6.1 Explanation of Service Role
- Components should only provide properties and methods for data binding
- Components should not define operations such as requesting data, user validation, etc.
- Various processing tasks should be defined in injectable services
- Service role: handle business logic, available for components
6.2 Service Description
- Use @Injectable() decorator to indicate a service
- Services need to register providers to be used
- Angular provides services to components through dependency injection (DI), i.e., components inject service dependencies without manual creation
- Recommended to register services used in the component in the constructor
6.3 Three Ways to Register Service Providers
(1) In the service file, register the service as a root provider via @Injectable() providedIn: 'root', making it available to all components in the project
- Inject and register the required service in the component, as shown below:
(2) In the module file, register as a provider of the module via @NgModule() providers: [], available only to components within the module
- Inject and register the required service in the component, as shown below:
(3) In the component file, register as a provider only available to the component and its subcomponents via @Component's providers: []
- HttpClient Description
Function: Send HTTP requests
- Wraps the XMLHttpRequest interface provided by the browser
- Uses an observable-based API
- Provides a streaming error handling mechanism for requests and responses
7.1 Using HttpClient
7.2 Get Full HTTP Resposne Content
// Add { observe: 'response' } after the request address
getData() {
this.http
.get('../../../assets/myData.json', { observe: 'response' })
.subscribe((res) => {
console.log(res); // All response content
console.log(res.body); // Response body
console.log(res.headers); // Response headers
console.log(res.headers.get('content-type')); // Response data type
console.log('etc');
});
}
7.3 Using TS Syntax to Constrain Response Data
- Constrain the get request and response res:
7.4 Request Failure Callback
getData() {
this.http.get<resInterface>('../../../assets/myData.json1').subscribe(
(res: resInterface) => {
console.log(res); // All response content
},
(err) => { // Failure callback
console.log(err);
}
);
}
7.5 Using json-server Plugin to Simulate Backend Interface
-
- Install:
npm i -g json-server
- Install:
-
- Create a json file, such as db.json
-
- Run json-server:
json-server db.json
- Run json-server:
-
- Request as follows:
get('url address')
post('url address',{parameter: 'value'})
delete(`{$this.url}/id value`)
patch(`{$this.url}/id value`,{parameter: 'new value'})
- Routing
8.1 Basic Steps to Configure Routing
- In the module file:
import { MyComp1Component } from "./my-module/my-comp1/my-comp1.component";//Import component
// 1. Import routing module
import { RouterModule, Routes } from "@angular/router";
// 2. Configure routing rules, and use Routes to constrain the routing format
const appRouters: Routes = [
{
path: 'mycomp1',
component: MyComp1Component
}
]
@NgModule({
declarations: [
AppComponent,
MyComp1Component,//Import the component used for routing display
],
imports: [
// 3. Configure the routing module, forRoot() ensures single routing service, preventing routing service errors
RouterModule.forRoot(appRouters)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
- HTML file routing outlet
<!-- 4. Configure route navigation -->
<button routerLink="/mycomp1">Display myComp1 component</button>
<!-- 5. Configure route outlet -->
<router-outlet></router-outlet>
8.2 Default Route, Redirection, Wildcard Route
const appRouters: Routes = [
{
// Default route, redirection
path: '',
redirectTo: '/mycomp1',
pathMatch: 'full'
},
{
// Wildcard route, redirect to 404 page when accessing non-existent route
path: '**',
component: NotFoundError
},
{
path: 'mycomp1',
component: MyComp1Component
}
]
8.3 Route Parameters
// One, configure the route file:
const appRouters: Routes = [
{
// Route parameters
// Can match: /perName/1 /perName/2 ...
// Cannot match: /perName /perName/1/1 ...
path: 'perName/:id',
component: PerNameComponent
}
]
// Two, navigation HTML
<button routerLink="/perName/1">Click 1</button>
<button routerLink="/perName/2">Click 2</button>
// Three, route component TS file
// 1. Import routing service
import { ActivatedRoute } from '@angular/router'
export class PerNameComponent implements OnInit {
constructor(
// 2. Declare
private route: ActivatedRoute
)
selectObj = [
{ id:1, name: 'xiaoming' },
{ id:2, name: 'xiaolan' }
]
activeName:any
ngOnInit(){
this.route.paramMap.subscribe(param => {
console.log(param)
const id = param.get('id')//Get route parameter
this.activeName = this.selectObj.find(item => item.id === +id) // Convert string type id to number type
}
// Four, route component HTML
<div>{{ activeName }}</div>
8.4 Nested Routing
// Route configuration file
const appRouters: Routes = [
{
path: 'father',
component: MyComp1Component,
// Sub-route
children: [
path: 'child1',
component: Child1Component
]
}
]
// HTML
<a routerLink = "/father/child1">Click</a>
<router-outlet></router-outlet>
8.5 Route Highlighting
// HTML
<a routerLink="/mycomp1" routerLinkActive="actived">Click 1</a>
<a routerLink="/mycomp2" routerLinkActive="actived">Click 1</a>
// Indicates exact match
<a routerLink="/mycomp3" routerLinkActive="actived" [routerLinkActiveOptions]="{exact: true}"></a>
// css
.actived {
color:red
}
- Programmatic Navigation
// 1. Import Router
import { Router } from '@angular/router'
export class MyComp1Component implements OnInit {
constructor(
// 2. Declare
private router: Router
) {}
// 3. Use
goTo() {
this.router.navigate(['/mycomp1'])
}
ngOnInit(): void {
}
}
- Reactive Forms
- Reactive forms (key point)
- Template-driven forms (based on template syntax, and two-way data binding directives, such as Angular's [ngModel], Vue's v-model)
Basic Usage Steps:
// One, module file:
// 1. Import
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
],
imports: [
// 2. Declare
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
// Two, TS file
import { Component } from '@angular/core';
// 3. Import
import { FormControl } from '@angular/forms'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
// 4. New
username = new FormControl('zrh')
password = new FormControl('123456')
// Get value
console.log(this.username.value)
// Update value
setUsername() {
this.username.setValue('newName')
}
}
// Three, HTML
<label>
Username:
<input type="text" [formControl]="username">
</label>
<p>{{username.value}}</p>
<label>
Password:
<input type="password" [formControl]="password">
</label>
<p>{{password.value}}</p>
For more information, please refer to the official documentation!