Angular
1, Preliminary start
1.1 INTRODUCTION
Angualr is an open-source web front-end framework developed by Google. It was born in 2009, created by Misko Hevery and others, and later acquired by Google. Is an excellent front-end JS framework, which has been used in many Google products.
According to the statistics of the number of projects, angular (1.x, 2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x) is the most used framework on the Internet.
Based on TypeScript, Angular is more suitable for medium and large enterprise projects than react and vue.
At present, the latest version of angular is angular9 on December 25, 2019 x. According to the official introduction, angular will update a version every few months. Angular2. The usage of all angular versions after X is the same, and this tutorial is also applicable to angular 7 x , Angular8.x,Angular9.x and other future versions
Note: learning Angular requires the foundation of TypeScript
1.2 installation of Angular Cli
- Operating environment: NodeJS
- Installing Angular Cli
- npm install -g @angular/cli
- Use ng v to view the version
Note: angular Cli has strict requirements on the node version. Pay attention to the node version prompted by the warning
1.3. Create and run projects
-
Create project
-
Ng new project name: for example, ng new testObj
-
Would you like to add Angular routing? //Install angular routing Mhich stylesheet fornat would you like to use?//Choose which css processor css scss sAss LESS Stglus
-
-
-
Installation dependency
- Enter the project directory and execute npm i
-
Run project
- Execute ng serve --open
IE8 does not support angular projects
1.4. Directory structure
app //Folder where components and root modules are placed assets //Static resource folder environments //Environment related folders .browserslistrc //Browser configuration support file favicon.ico //Web page icon index.html //Entry file karma.conf.js //End to end test file main.js //Project entry file polyfill.js //Project population Library styles.css //Common style file, the file type is determined when the project is created test.ts //Test entry file package.json //npm profile
2, Foundation
2.1. Create components
The terminal executes ng g view to create a new file type
ng g type name specifies the directory
#Example: create a new component to the news folder in the components under the app ng g component components/news
The component path depends on the default app folder as the root directory
- Components created with the command will automatically create corresponding CSS, HTML and ts files
- And will be on app module. Automatic introduction and configuration in TS
2.2. Component data binding
- Define data in component ts file
import { Component, OnInit } from '@angular/core'; @Component({ selector: '...', //Use the name of this component templateUrl: '...', //html for this component styleUrls: ['...'] //css for this component }) //Syntax refers to classes in typescript export class NewsComponent implements OnInit { public newsTitle = "Daily News" // msg:string = 'The temperature is high today' //Without the attribute modifier, typescript will default to public //The definition data should specify a data type (typescript specification constructor() { } //Constructor ngOnInit(): void { } }
- Using data in html
<!-- In the corresponding html Data used in --> <h2>I'm the news component</h2> <ul> <li>{{newsTitle}}</li> </ul> <!-- Class formula Vue Syntax, but there can be more than one root component in the component-->
2.3. Binding attribute value
<!-- use[]Dynamic binding properties similar v-bind--> <!-- [Attribute name]="data/Data variable name" --> <div [title]="titleInfor"> mouse hover,Show me how to dynamically bind attributes </div>
2.4 parsing html code
<!-- use[innerHTML]analysis HTML code, similar v-html --> <!-- Use with caution and may Vue It is also prone to network attacks --> <span [innerHTML]="content"></span>
2.5. Attribute traversal
<!-- *ngFor Cycle, Similar formula in v-for --> <ul> <li *ngFor="let item of newsList;let i=index;let odd=odd;let even=even;let f=first;let l=last"> <p>{{item}}</p> <p>index:{{i}}</p> <p>is odd :{{odd}}</p> <p>is even :{{even}}</p> <p>First:{{f}}</p> <p>Is it the last one:{{l}}</p> </li> </ul> <!-- be careful: ngFor of index It is required to declare variable reception and provide other additional parameters --> <!-- Angular Loop traversal in, no need to add key -->
2.6 icon introduction
<!-- assets Pictures in resource folders --> <!-- No need to write relative picture directory, default from assets folders finding --> <img src="assets/image/icon-yellow_03.png" alt=""> <!-- Bind dynamic picture address --> <img [src]="imgSrc" alt=""> <!-- stay ts When defining a picture path from a file assets start --> // You do not need to write a relative picture directory. By default, you can find it from the assets folder public imgSrc ='assets/image/icon-yellow_05.png'
2.7 conditional rendering
- gnIf
- Similar to v-if
<!-- gnIf --> <p *ngIf="ifShow">by true When I show</p> <!-- gnIf--ngIf-else --> <ng-container *ngIf="ifShow; else elseTemplate"> <p>by true When I show</p> </ng-container> <ng-template #elseTemplate> <p>by false When I show</p> </ng-template>
- ngSwitch
<!-- ngSwitch --> <span [ngSwitch]="stateNum"> <p *ngSwitchCase=1> 1 Indicates failure </p> <p *ngSwitchCase=2> 2 Indicates success </p> <p *ngSwitchDefault> Default </p> </span>
2.8 binding properties and styles
- ngClass
<!-- ngClass --> <!-- [ngClass]="{'class1': true} key Is the property name, value Is a Boolean value when value by true,The attribute is displayed --> <div [ngClass]="{'class1': true,'nn':false}"> I demonstrate ngClass </div>
- ngStyle
<!-- ngStyle --> <!-- [ngStyle]="{'Attribute name': 'Attribute value','fontWeight':'bold'} --> <!-- Attribute names can be humped or not --> <!-- Note: attribute values are not added''Indicates that a variable is used instead of a property string --> <div [ngStyle]="{'color': 'red','fontWeight':'bold'}"> I'm demonstrating ngStyle </div>
2.9 event binding
<!-- use(Event name)="Method name()" --> <!-- use $event Incoming event object --> <p (click)="run($event)">Point me! {{str}} </p> <input type="text" (keyup)="inputFn($event)">
ts file
... export class HeaderComponent implements OnInit { ... public str = 'FBI open door!!!' ... constructor() { } ngOnInit(): void { } // Custom method run(e:any):void{ alert('Run!!!') // Change data this.str = 'FBI incoming !!!' console.log(e) } // Parameter must specify type inputFn(e:any):void{ console.log(e) } }
2.10 bidirectional binding
- Note that you need to enter the app module. TS import FormsModule
... // FormsModule implements bidirectional binding import { FormsModule } from '@angular/forms'; @NgModule({ declarations: [ //Configure the running components of the current project ... ], imports: [ //Configure other modules on which the current module depends .... FormsModule ], ... }) ...
- Use bidirectional binding
<!-- Need in app.module.ts introduce FormsModule similar v-model--> <input type="text" [(ngModel)]="bdstr"> <p>{{bdstr}}</p>
3, Pipeline
The function and usage of pipe are similar to the filter in Vue
3.1. angular official common pipeline
- toggle case
<p>{{'Str' | uppercase}}</p>//Convert to uppercase <p>{{'Str' | lowercase}}</p>//Convert to lowercase
- toggle case
<p>{{new Date().getTime() | date:'yyyy-MM-dd HH:mm:ss' }}</p>
3.2. Custom pipe
Create using ng g pipe placement directory / pipe name
For example, create a mydemo pipe under the pipe under the app
ng g pipe pipe/mydemo
The following is the contents of the pipeline ts file
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ // Define reference pipe name name: 'mydemo' }) export class MydemoPipe implements PipeTransform { // transform(value: unknown, ...args: unknown[]): unknown { // return null; // } // Custom pipeline function (fixed function name as transform) transform(value: string): string { if(!value) return value; if(typeof value !== 'string') { throw new Error('Invalid pipe argument for WelcomePipe'); } return "Welcome to " + value; } }
app. module. Inlet pipe in TS
// Lead in pipe import { MydemoPipe } from './pipe/mydemo.pipe'; //Configuration pipeline @NgModule({ declarations: [ //Configure the running components of the current project MydemoPipe ], )}
Using custom pipes
<!-- Custom pipe --> <p>{{ 'Tianjin' | mydemo }}</p>
4, Two way binding form exercise
- toDoList
- search
5, Service
Store public methods or properties, create multiple services, and call each other between services
5.1. Create service
ng g service specifies the directory / service name
5.2 introduction of services
Feels like VueX in Vue?
-
On app module. In TS
// Introduction Service //MyserviceService is myservice Class name exposed in service import { MyserviceService } from './services/myservice.service' @NgModule({ declarations: [ //Configure the running components of the current project ... ], imports: [ //Configure other modules on which the current module depends ... ], providers: [ MyserviceService ], //Configure the services required by the project ... })
-
In component
// The services to be used by this component are introduced import { MyserviceService } from '../../services/myservice.service' export class TodolistComponent implements OnInit { ... // Initialize service // Dependency injection??? //public custom variable name: the name of the imported service constructor(public myserve:MyserviceService) { } ngOnInit(): void { // Using methods in services this.myserve.show() } }
5.3 persistence
Implemented through sessionStorage or localStorage
6, ViewChild
Similar to ref in Vue?
6.1. Get dom node
//Introducing ViewChild into component ts import { Component, OnInit,ViewChild,... } from '@angular/core'; //Use in html # Custom name Identify dom nodes /* <div #mybox> I'm a div bound to ViewChild </div> */ //Get the dom node using the ViewChild modifier export class ViewchildComponent implements OnInit { //@Viewchild ('name of using # binding on DOM ') custom variable name: any @ViewChild('mybox') aaa:any constructor() { } ngOnInit(): void { } ngAfterViewInit(): void { console.log(this.aaa,'Print mybox') } }
6.2. Obtaining sub components
//Binding subcomponent app news /* <!-- Binding components -- > <app-news #news></app-news> */ //Using subcomponent methods export class ViewchildComponent implements OnInit { //Get subcomponents through ViewChild @ViewChild('news') news:any constructor() { } ngOnInit(): void { } ngAfterViewInit(): void { //View subcomponent information console.log(this.news,'Print news') // Calling subcomponent methods this.news.say() } }
7, Components
7.1 parent child components
7.2 component communication
7.2. 1. Parent component passes value to child component
@input is similar to props in Vue
The parent component can not only pass data to the child component, but also pass its own methods and the whole parent component to the child component
- In parent component
<!-- Bind the data of the parent component to the child component --> <!-- The following are the parent component data Parent component method parent component itself --> <app-search [msg]="message" [fn]='run' [fcpn]='this'></app-search>
- In subcomponents
// The Input module is introduced into the sub component import { Component, OnInit,Input } from '@angular/core'; export class SearchComponent implements OnInit { ... // Binding data using the Input modifier @Input() msg:any @Input() fn:any @Input() fcpn:any constructor() { } ngOnInit(): void { console.log(this.msg,'Data passed by parent component') // Execute parent component method this.fn() // console.log('execute parent component method ') // Output parent component console.log(this.fcpn,'Output parent component') } }
7.2. 2. The child component passes values to the parent component
There are two methods:
- Get subcomponents using ViewChild
- Use @ Output to trigger the parent component, similar to $emit in Vue
//Introduce in subcomponents Output,EventEmitter modular import { Component, OnInit,Input ,Output,EventEmitter} from '@angular/core'; export class SearchComponent implements OnInit { ... //Declare variables through the Output modifier to receive and instantiate EventEmitter @Output() private myouter = new EventEmitter constructor() { } ... // Pass value to parent component doting(){ // Broadcast data console.log(111) this.myouter.emit('I am the data passed from the child component to the parent component') } } <!-- In parent component --> <app-search (myouter)="getChild($event)"></app-search> <!-- getChild Is the method of the parent component, and its parameters $event Parameters passed for subcomponents -->
8, Life cycle
- ngOnChanges - called when the value of the data binding input property changes
- ngOnInit - after the first ngOnChanges, the call / / component and instruction initialization is completed, not the real dom load completion.
- ngDoCheck - a custom method for detecting and processing changes in values
- ngAfterContentInit - call after component content initialization
- ngAfterContentChecked - called each time the component checks the content
- After the ngAfterViewInit - component view is initialized, it is invoked / / recommended to operate dom here.
- ngAfterViewChecked - called each time the component checks the view
- ngOnDestroy - call before destruction
Function name | describe |
---|---|
constructor | Constructors should do nothing but initialize local variables with simple values. (it is not a lifecycle function) |
ngOnChanges | Respond when Angular (resets) the data binding input property. This method accepts the SimpleChange object of the current and previous property values. When the bound input property value changes, the first call must occur before ngOnInit. |
ngOnInit | After Angular displays the data binding for the first time and sets the input properties of the instruction / component, initialize the instruction / component. After the completion of the first round of ngOnChanges (), it is called only once. = = = = = = = There are two reasons for using ngOnInit: 1. Execute complex initialization logic immediately after the constructor; 2. After Angular sets the input properties, prepare the component. |
ngDoCheck | Check and execute in ngOnInit. Data can be checked during this lifecycle |
ngAfterContentInit | After the component is rendered, the periodic function is called after the content is projected into the component. After the first ngDoCheck, it is called only once. |
ngAfterContentChecked | Check, similar to ngDoCheck |
ngAfterViewInit | After the view is loaded, it is called. After the first ngAfterContentChecked (), it is called only once. |
ngAfterViewChecked | Check, similar to ngDoCheck |
ngOnDestroy | Call before component destruction |
// The specification corresponding to the life function is followed by the implements, which may not be introduced // If it is introduced, it shall be written according to its specifications // Use when introducing multiple, split export class LifefnComponent implements OnInit { public msg:string = '' constructor() { console.log('00---I am constructor Constructor') } ngOnChanges(): void { console.log('01---I am ngOnChanges Life cycle function') } ngOnInit(): void { console.log('02---I am ngOnInit Life cycle function') } ngDoCheck(): void { console.log('03---I am ngDoCheck Life cycle function') } ngAfterContentInit(): void { console.log('04---I am ngAfterContentInit Life cycle function') } ngAfterContentChecked(): void { console.log('05---I am ngAfterContentChecked Life cycle function') } ngAfterViewInit(): void { console.log('06---I am ngAfterViewInit Life cycle function') } ngAfterViewChecked(): void { console.log('07---I am ngAfterViewChecked Life cycle function') } ngOnDestroy(): void { console.log('08---I am ngOnDestroy Life cycle function') } }
9, RxJS
9.1 introduction
RxJS is a JavaScript version of the ReactiveX programming philosophy. ReactiveX comes from Microsoft. It is a kind of programming for asynchronous data flow. In short, it packages all data, including HTTP requests, DOM events or ordinary data, into a stream form, and then processes it with powerful and rich operator streams, so that you can process asynchronous data in a synchronous programming way, and combine different operators to easily and gracefully realize the functions you need.
RxJS is a programming tool for asynchronous data flow, or responsive extended programming; However, no matter how RxJS is interpreted, its goal is asynchronous programming. Angular introduced RxJS to make asynchronous controllable and simpler.
Popular understanding: RxJS is mainly used for asynchronous programming, similar to Promise, but more powerful.
RxJS is a third-party module, but Angular has integrated RxJS to make asynchronous controllable and simpler.
Common asynchronous programming methods at present:
- Callback function
- Event listening / publish subscribe
- Promise
- RxJS
9.2 asynchronous comparison between Promise and RxJS
The method of use is similar
However, rxjs can be withdrawn halfway, rxjs can emit multiple values, rxjs provides a variety of tool functions, and so on.
// Use RxJS in the files used // Observable with RxJS import { observable, Observable } from 'rxjs'; #Define function ... // Promise getPromiseData(){ return new Promise((resolve,reject) => { setTimeout(() => { let data = { name:'Zhang San', age:16 } resolve(data) }, 2000); }) } // RxJS getRxjsData(){ return new Observable((observer) =>{ setTimeout(() => { let data = { name:'Zhang San', age:16 } observer.next(data) //Successfully called next method // observer.error('error ') / / call failed Error method }, 2000); }) } #call //3. promise to obtain asynchronous data this.myserve.getPromiseData().then((res) => { console.log(res,'Promise') }) // 4.RxJS obtains asynchronous data this.myserve.getRxjsData().subscribe((res) => { console.log(res,'RxJS') })
9.3 unsubscribe unsubscribe
After Promise is created, the action cannot be undone Unlike Observable, actions can be withdrawn halfway through the unsubscribe method
// 5. Use unsubscribe to withdraw // If the asynchronous method has not been executed, it can be withdrawn let rxjsFn = this.myserve.getRxjsData() let data2 = rxjsFn.subscribe((res) => { console.log(data,'RxJS of subscribe value') }) // Cancel with the value of subscribe // Effect: cancel the execution of getRxjsData after one second setTimeout(() => { // Unsubscribe unsubscribe data2.unsubscribe() }, 1000);//The delay time here is less than the delay in getRxjsData (simulated withdrawal before asynchronous function execution)
9.4. Multiple subscription execution
#Defined in serve // Perform comparison multiple times // Promise getPromiseDataInterval(){ return new Promise((resolve,reject) => { setInterval(() => { let data = { name:'Zhang San', age:16 } resolve(data) },1000) }) } // RxJS getRxjsDataInterval(){ return new Observable((observe) => { setInterval(() =>{ let data = { name:'Zhang San', age:16 } observe.next(data) },1000) }) } #quote // 6.Promise is executed multiple times (promise can't do it) let p2 = this.myserve.getPromiseDataInterval() p2.then((res) => { console.log(res,'Promise Multiple execution') }) // 7.RxJS is executed multiple times let r2 = this.myserve.getRxjsDataInterval() r2.subscribe((res) => { console.log(res,'RxJS Multiple execution') })
9.5,Angular6. Tool functions using RxJS before x
**Note: * * RxJS version after Angular6 is 6 x. If you want to be in Angular6 The method before x uses RxJS6 For some methods in version x, the RxJS compat module must be installed to use map and filter
After angular6, the official uses the new features of RxJS6, so the official gives a way to temporarily delay us from modifying rsjx code.
- install
- npm install rxjs-compat
9.6,Angular6. Rxjs6 after X Changes and use of X
Angular6. For use after X, you do not need to install rxjs compat
RxJS6 has changed the package structure, mainly in the import method and operator, and the use of pipe()
-
Introduction module
-
//Introduce modules into the components used // Introduce the map and filter tool module of RxJS import { map,filter } from 'rxjs/operators'
-
-
use
-
// 8. Process the data through tools and methods let num = this.myserve.getRxjsNumInterval() // Using tool methods in pipe // filter returns the value that meets the condition // num.pipe( // filter((item:any) =>{ // return item%2 == 0 // }) // ).subscribe((res) => { // console.log(res,'-----filter') // }) // map is a variable, similar to that in ES5 // num.pipe( // map((item:any) => { // return item * item // }) // ).subscribe((res) => { // console.log(res,'-----map') // }) // You can use multiple methods in a pipe num.pipe( filter((item:any) => { return item%2 ==0 }), map((item) => { return item * item }) ).subscribe((res) => { console.log(res,'-----Combined use of multiple tools') })
-
9.7 RxJS delayed execution
Implemented via throttleTime
//introduce import { throttleTime } from 'rxjs/operators' //use let rxjsFn = this.myserve.getRxjsData() rxjsFn.pipe( throttleTime(1000) ).subscribe((res) => { console.log(res) })
10, Data interaction
10.1. Angular comes with HttpClientModule
Angular5. The HttpClientModule module is used for get, post and server interaction after X
-
introduce
-
//On app moudle. The HttpClientModule module is introduced into ts and configured // HttpClientMidule module is introduced to realize data interaction import { HttpClientModule } from '@angular/common/http' ... @NgModule({ declarations: [ //Configure the running components of the current project ....], imports: [ //Configure other modules on which the current module depends ... HttpClientModule ], ... }) ...
-
-
Import in component
-
// The HttpClient module is introduced into the component, which can be borrowed as a service of the HttpClientModule module module import { HttpClient } from '@angular/common/http';
-
-
Declare services and use methods
-
export class NetworkComponent implements OnInit { // Claim service constructor(private myhttp:HttpClient) { } // get method getData(){ let url = 'http://a.itying.com/api/productlist' //HttpClicent returns an RxJS object. Call with subscribe this.myhttp.get(url).subscribe((res) => { console.log(res) }) } // post submit data postData(){ // Manually define request headers const myHttpOptions = { headers :new HttpHeaders({'Content-Type':'application/json'}) } this.myhttp.post('http://47.104.7.144:3001/api/adminlogin', {"name":'ICPFAadmin',"pwd":'admin'}, // myHttpOptions ).subscribe((res) => { console.log(res) }) } }
-
10.2. Third party axios
-
install
- npm install axios --save
-
introduce
-
It is recommended to introduce in the service file
-
// Introducing axios import axios from 'axios'; export class AxiosService { axiosGetData(){ // Return axios and call it externally then method return axios({ url:'http://47.104.7.144:3001/api/adminlogin', method:'post', data:{ name:'ICPFAadmin', pwd:'admin' } }) } }
-
-
use
-
// Introduce services into required components import { AxiosService } from 'src/app/services/axios.service'; ... export class AxiosComponent implements OnInit { // Claim service constructor(private myaxios:AxiosService) { } ngOnInit(): void { // Using axios in services this.myaxios.axiosGetData().then((res) => { console.log(res,'axios') }) } }
-
11, Routing
-
When creating a project, select Install route to create a new project containing route
-
If routing is not installed when creating the project, you can create a new app routing in the app directory module. TS routing profile
-
// Routing configuration module import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
-
-
And in app module. TS import and configure
-
//Import routing profile import { AppRoutingModule } from './app-routing.module'; ... @NgModule({ declarations: [ ... ], imports: [ //Configure other modules on which the current module depends AppRoutingModule, ... ], providers: [ ... ], //Configure the services required by the project bootstrap: [AppComponent] })
-
-
On app component. Add in HTML
-
<!-- amount to Vue Medium router-view label --> <router-outlet></router-outlet>
-
11.1. Configure routing
-
Introduce the corresponding components in the routing file
-
// Routing configuration module import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; // Introduce components required for routing import { NewsComponent } from './components/news/news.component'; import { TodolistComponent } from './components/todolist/todolist.component'; // Configure routing const routes: Routes = [ { // route path:'home', // Corresponding components component:TodolistComponent }, { path:'news', component:NewsComponent }, // Redirection method I // { // path:'', // //Redirect // redirectTo:'home', // pathMatch:'full' // } // Redirection method 2 { path:'**', // redirect redirectTo:'news', } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
-
11.2 routing parameters
-
Configure routing
-
// Dynamic routing value transmission { path:'router/:routedata', component:RouterComponent }, // get pass parameter // { // path:'router', // component:RouterComponent // },
-
-
transmit
<!-- There are two ways to use get Value transmission --> <!-- Method 1: dynamic routing --> <a [routerLink]="[ '/router', 'I'm data' ]">Routing value---params</a> <!-- Method 2 get method --> <a [routerLink]="[ '/router']" [queryParams]="{myid:1,name:'Zhang San'}">Routing value---queryParams</a>
-
obtain
-
Introducing ActivatedRoute into a component
-
// Introducing the ActivatedRoute module import { ActivatedRoute } from '@angular/router'; ... export class RouterComponent implements OnInit { // Declare ActivatedRoute constructor(public myactiveroute:ActivatedRoute) { } ngOnInit(): void { console.log(this.myactiveroute,'Currently active route') //The return value is an RxJS object, which needs to be called with subscribe //Method 1 this.myactiveroute.params.subscribe((res) => { console.log(res,'Routing parameters---params') }) //Method 2 this.myactiveroute.queryParams.subscribe((res) => { console.log(res,'Routing parameters---queryParams') }) } }
-
11.3 event jump
- Dynamic route and normal route jump
// Introducing Router import { Router } from '@angular/router'; ... export class RoutermainComponent implements OnInit { // statement constructor(public myrouter:Router) { } ngOnInit(): void { } goPage(){ // Dynamic routing this.myrouter.navigate(['/router','I am dynamically routing data']) } goHome(){ // General routing this.myrouter.navigate(['/home']) } }
- get route jump
// Introducing Router // The event jump get route also needs to introduce NavigationExtras import { Router,NavigationExtras } from '@angular/router'; export class RoutermainComponent implements OnInit { // statement constructor(public myrouter:Router) { } ... goGet(){ // Get route // Define the passed data and specify the type as NavigationExtras let myqureyData:NavigationExtras = { queryParams:{ name:'Wow, ha ha', age:12 } } this.myrouter.navigate(['/routerget'],myqureyData) } }
11.4 nested routing
//Configure routing { path:'routermain', component:RoutermainComponent, children:[ { path:'child', component:RouterchildComponent } ] },
<!-- Jump --> <a [routerLink]="[ '/routermain/child' ]">To sub route</a> <router-outlet></router-outlet>