Write in front
Since the relevant technical documents of Angular 4 on the Internet are not very sufficient, I wrote a record document for this pit. On the one hand, I want to record various problems and personal understandings I encountered in the project. On the other hand, I also think that some pits may also be encountered, and I can also give a reference to fellow Taoists. There are many shortcomings in the document, and I will gradually improve it in the later stage. I also hope that fellow Taoists can point out the incorrect and optimized areas in the document in a timely manner.
I plan to divide this help document into 4 chapters:
Chapter 1:
About some questions and operation steps of angular 4 + ng-zorro in basic layout and module splitting
Chapter 2:
angular 4 Introduction to routing => Component modularity #module modularity => Route modularity (routing loads on demand)
Chapter 3:
Introduce interceptors, unified management requests and corresponding =>Introduce http services for communication =>Introduce service services for communication with the background =>Split service services =>Use observer mode to publish and subscribe data
Chapter 4:
Project Packaging => Optimization
============================= Begin ===============================
Chapter 1: Some questions and operation steps about angular 4 + ng-zorro in basic layout and module splitting
Before using Ng-zorro launched by Alibaba Dad, I hope you can make sure that the local angular-cli version is the latest version, and the current latest version is 1.6.3 (2018/1/10) * Compatibility issues may cause the department js to be lost after the later project is packaged.
If you have installed cli globally or have created angular projects using relatively old versions, you can update your local cli version and compatible with the project using the following command:
First, you need to uninstall the local angular-cli installation package:
npm uninstall -g angular-cli npm uninstall --save-dev angular-cli
Install the latest version of the cli package globally:
npm uninstall -g @angular/cli npm cache clean npm install -g @angular/cli@latest
You can use ng -v to see the local current version of cli through the cmd command line. If you have installed the latest version, you can use the new version of the ng command: [ng new "Project Name"] to create a new angular project. If you already have an angular project, you need to update the cli version in the project. The specific commands are as follows:
rmdir -rf node_modules dist npm install --save-dev @angular/cli@latest npm install
If you have completed the above operation, you can open it and see that the cli version in your project has been replaced with the latest version.
When using ng-zorro, two points need to be paid attention to:
Ng-zorro cannot be introduced at once and used in multiple components. If there are child modules in your project, the relevant dependency packages need to be introduced in the child module. It should be noted that you must use it through the forRoot() method in the module.
//Main moduleimports: [ BrowserModule, FormsModule, HttpClientModule, (), BrowserAnimationsModule ]
In the submodule, the forRoot() method is no longer needed:
//Submoduleimports: [ CommonModule, HttpClientModule, NgZorroAntdModule ]
Once you have introduced the required files, you can start using ng-zorro.
Chapter 2: angular 4 Introducing routing => Component modularization #module modularization => Route modularization (routing loads on demand)
2.1 angular 4 Introduce routing
import { NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { NgZorroAntdModule } from 'ng-zorro-antd'; import { RouterModule, Routes } from '@angular/router'; import {HashLocationStrategy , LocationStrategy} from '@angular/common'; import { HTTP_INTERCEPTORS } from '@angular/common/http';
//Main moduleimports: [ BrowserModule, FormsModule, HttpClientModule, (), BrowserAnimationsModule ]
//Submoduleimports: [ CommonModule, HttpClientModule, NgZorroAntdModule ],
After angular imports module, the route will be placed in a file for importing. You need to import it in the main module and then export it in the main module. If you have a child module, then you need to import it in the child module and export it in the child module, because Routermodule, as a work as a management route, will import multiple templates into the same template. If you need to split the routing file in your project or if you want to load on demand and lazy load related functions, then you may need to associate the routes with each other. In Vue, you can link them through some syntax of ES6, and angular 4 provides the corresponding link to respond to loadChildren. The specific code is as follows:
imports: [ BrowserModule, FormsModule, HttpClientModule, (), BrowserAnimationsModule, EventAnalysisModule, ( appRoutes ) ], exports: [ RouterModule ],
imports: [ CommonModule, FormsModule, ReactiveFormsModule , NgxEchartsModule, HttpClientModule, NgZorroAntdModule, (EVENTROUTES) ], exports: [ RouterModule ],
routerModule contains two key methods, forRoot() and forChild()
These two methods, as a control to display multiple modules in the same module, play a key role in the parent-child module, which is also a key step for LoadChildren to take effect.
//Routing configuration file { path: 'index', component: NzDemoLayoutTopSide2Component, children: [ { path: 'event', loadChildren: './event/#EventAnalysisModule' } ] },
//EventAnalysisModule routing part { path: 'eventAnalysis', component: EventAanlysisComponent, children: [ { path: 'overview', component: OverviewComponent }, { path: 'CreditEvaluation', component: CreditEvaluationComponent }, { path: 'loanHistroy', component: LoanHistroyComponent }, { path: 'userInfo', component: UserInfoComponent } ] }
If your project is relatively large and needs to modularize the route or perform some lazy loading or on-demand loading functions, you need to contact the route through loadChildren. Since loadChildren needs to rely on the file imported by the outermost route, you need to write the path of the module you imported in the routing parameters, instead of importing it in the form of import, and you need to use # to split the path and the imported module name.
Chapter 3: Introduce interceptors, manage requests and corresponding
If you use axios, you may have used its interception function, which allows us to handle issues such as identity authentication, error handling and server status codes in a unified manner, without having to deal with each page separately. Angular is also very simple in implementing the interceptor function, and you only need to implement the HttpInterceptor interface.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const clonedRequest = ({ headers: ('Content-Type', 'text/plain;charset=UTF-8') });
The intercept method has two parameters, one is request and the other is next to call the next "middleware".
According to the writing method of the angular official website document, request has a clone method, which can process our request and add response parameters to the request, such as token, header, browser cookies, etc.
Finally, you need to pass your request parameter to the next middleware, and here it is done after return, like this:
return (clonedRequest)
In the process of response processing, there are many situations. You need to return the correct request to the corresponding component and handle the exception requests in a unified manner. This process is an observable mode. We need to use mergeMap, do and other rxjs operators to process it.
return (clonedRequest) .mergeMap((event: any) => { // Handle exceptions reurn (Observable => (event)); }) .catch((res: HttpResponse<any>) => { return (res); })
Use catch to capture and return to the component. The following is the code for the entire interceptor. If necessary, you can introduce it. Of course, you also need to introduce it in the main module now to take effect normally:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; providers: [MyService, { provide: LocationStrategy, useClass: HashLocationStrategy }, { provide: HTTP_INTERCEPTORS, useClass: NoopInterceptor, multi: true, }, ApiModule]
Interceptor code:
import { Injectable } from '@angular/core'; import { Observable } from "rxjs/Observable"; import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/mergeMap'; // The thorw method needs to be introduced separatelyimport 'rxjs/add/observable/throw'; import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse} from '@angular/common/http'; @Injectable() export class NoopInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const clonedRequest = ({ headers: ('Content-Type', 'text/plain;charset=UTF-8') }); // ("new headers", ()); return (clonedRequest) .mergeMap((event: any) => { // if (event instanceof HttpResponse) { // return (Observable => (event)); // } return (Observable => (event)); }) .catch((res: HttpResponse<any>) => { return (res); }) } }
Regarding the usage of mergeMap and the entire interceptor, the masters on sf also gave detailed explanations:
Click to open the link
Introduce http service for communication
After you introduce angular interceptor, you can manage the request headers of the requests in a unified manner, and can centrally handle all request response bodies and exceptions. Then the http request becomes very simple. There are many examples about how to write requests on the official website and on the Internet, and you can also encapsulate the request method to use.
Introduce service services to interact with the background
When using angular4, I want to use the service as a place to store public data. Then the public data and parameters of different components can be stored in the service. If the shared data is always not the latest in some scenarios, since this is the case, why not place the data source in the service according to the official demo, and then obtain the data through subscription or promise? In this way, when different components use some shared data, they can be guaranteed to be the latest data, which is more convenient to use.
Since the subscription is mentioned, we have to talk about the observer mode. Observer mode is also known as the publish subscription mode. It defines a one-to-one-to-many relationship network. Simply put, let multiple observers observe an object. When any changes occur in the observed object, all observers who subscribe to it will receive the message in a timely manner and update it in a timely manner. This feeling is very similar to subscribing to newspapers. After subscribing to newspapers, whenever a new newspaper is published, it will be delivered to you to let you know the latest news, but if you unsubscribe to newspapers, you will not receive the latest version of newspapers. So what are the two characters represented by the observer and observers? In fact, it is subject and observer. Regarding the use of subject and observer, there is a very comprehensive introduction to sf:Click to open the link
It is very simple to use. Just enter the code:
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { ApiModule } from '../api/api'; import { Subject } from 'rxjs/Subject'; import 'rxjs/add/operator/retry'; @Injectable() // How to log in public LoginSubject = new Subject<any>(); public getUserInfo(name, pwd):void { var data = {"username":name,"password":pwd}; var val = ; this.$http .post(`${val}/login`, data) .retry(3) .subscribe( res => { (res) }); }
The subject is created in the form of new. After your server data is returned, you can use next to pass the corresponding stream to the subject you defined. This is how the service layer is written, so how do you subscribe to the component? On code:
(name, password) = ( data => { here is your code }
The service needs to be declared in the constructor, so I won't write it here. The getUserInfo method in the service accepts two parameters, name and password, and publishes it here, and you can subscribe next. Since sometimes, we hope that when we subscribe for the second time, we will not receive the value emitted by Observable from the beginning, but will start sending from the value currently being processed for the first subscription, so the entire process needs to be processed accordingly. Generally speaking, we will not take the initiative to unsubscribe, but we may need to unsubscribe depending on the business situation. How to do it? Directly upload the code:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { HttpClient, HttpHeaders } from '@angular/common/http' import { ApiModule } from '../api/api'; import { MyService } from '../myService/'; import {NzMessageService} from 'ng-zorro-antd'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'login-component', templateUrl: './', styleUrls: [ './' ] }) export class LoginComponent implements OnInit { subscript: Subscription constructor (private router:Router, private service: MyService, private _message: NzMessageService,) { = new Subscription() } } ngOnInit ():void { (name, password) = ( data => { // here is your code } () } }
This is the whole process from creating the observer => Publish => Subscribe => Unsubscribe.
Split service
As your business increases, it is impossible for you to use only one service to support the service. You need to introduce multiple services to communicate with the server. Service modularization is actually very simple. Just pay attention to the location of the service provider. Due to different projects, we will not list specific examples.
Chapter 4: Package and release
Every time I always have little hands trembling, worried that various problems will arise during the packaging process. I will list some simple common problems that may arise after packaging. If you don’t encounter it, you can go to the programmer’s old calendar to check it. You may be suitable for packaging and testing today. If you encounter it, that’s great, I will share these pitfalls with fellow Taoists.
(1) Version issue
Since the entire project is done in combination with ng-zorro, it may be due to the cli version problem. If the department button fails or the department style is lost after packaging, then you can try to update your global cli version and the cli version in the project. I have already written the specific update method at the beginning.
(2) The problem of server refresh route loss (hash/histroy mode)
Import HashLocationStrategy and HashLocationStrategy to enable hash mode.
import {HashLocationStrategy , LocationStrategy} from '@angular/common'; @NgModule({ declarations: [AppCmp], bootstrap: [AppCmp], imports: [BrowserModule, routes], providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}] });
If you package it again, there will be no problem with refreshing 404.
(3) Problem that the server cannot load after opening
If you can't open it after deployment, you can check whether you are placed in the file in the root directory of the server. If not, you can modify the packaged file and find <base href="/" rel="external nofollow" > Modify href to './' and it' is OK
(4) The file size is too large, and optimization problems.
You can enable detailed compilation through ng build --prod, it will delete all modules and codes that you cannot use, and --pord will enable -aot compilation by default.
You can also use nginx gzip to optimize operations. Here is an article by fellow Taoists, which has done a lot of optimization processing. It is very awesome. I will share it with you:Click to open the link
Ending:
This is some problems that I personally amazed in this angular project. I will record them and share them with you. They are all things I understand and learned from Baidu. There may be errors, and some codes may be for your reference only. I also hope that fellow Taoists can point out the shortcomings and communicate actively
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.