Strive for the first wheels in Angular 5
Github:github.com/OrangeXC/ud… Link: incompetent-plantation.surge.sh/
The latest wheel is more designed to give beginners a reference example, according to the current feedback, if the technology stack does not match, few people will click in to read, we can consider changing the blog type in the future.
I wrote a post about Angular2 from Build to development, which got 4th place in the Top Writer articles list for Q4 2016 on segmentFault, and now angular 5
The common perception is that big releases cause breaking change, because Angular goes from 1.x to 2.x with two frames.
Angular 1.x is angular.js, and angular 2.x will be angular, hosted on two Github repOs.
Js star is close to Angular double, and the community is thriving. This article is looking for components that work with Angular 5. The framework has just been updated, and the corresponding components have not been updated yet.
Angular 2 to 4 to 5, the number of components decreases exponentially, but the good news is that it can be easily extended backwards, so this project is completely understandable if you are familiar with Angular 2.
In fact, who can write wheels to see the document, I try to say more pits, let developers less pit.
Roll up your sleeves.
Setting up the development environment
NPM install - g @ presents/[email protected]Copy the code
Here you point the version directly to 1.5.0
ng new PROJECT-NAME
cd PROJECT-NAMECopy the code
At this point the dependency is installed. Run ng -v and you can see the following
ng serveCopy the code
By default, port 4200, you can see the initialization page.
The installation process may take a long time. You are advised to install YARN on the local PC first. During dependency installation, the CLI automatically uses YARN to install dependencies, which is much faster.
It’s ready to be developed here.
The development of
The public interface of udAO dictionary is deprecated, the interface presented here is unofficial and supports limited functionality
The UI library is ng-bootstrap, and ngx-loading is used
There will be a dependency version inconsistency warning during installation, as follows
Angular [some component] is an angular 1. X component named ng-ng2 -, Search NGX -[some component].
Ng-bootstrap supports only bootstrap4, which supports 3 and 4. In order to avoid version disputes, Ng-bootstrap is used directly.
Far from proving that Angular 5 can use the library, my criteria is Angular 4. If it supports Angular 4, then 90% support Angular 5, because the changes are really small.
routing
There are only four routes involved in this project so far.
/
The home page/translate
translation/search
Fuzzy search/detail/:word
Details of the word
Define routes under app.module.ts
const routes: Routes = [
{
path: ' '.component: HomeComponent
}, {
path: 'translate'.component: TranslateComponent
}, {
path: 'search'.component: SearchComponent
}, {
path: 'detail/:word'.component: DetailComponent
}
]Copy the code
Here’s the problem with routing jumps. Angular 5 still has a-tag jumps and JS jumps
- A Label
@Directive({ selector: ':not(a)[routerLink]' })
class RouterLink {
queryParams: {[k: string]: any}
fragment: string
queryParamsHandling: QueryParamsHandling
preserveFragment: boolean
skipLocationChange: boolean
replaceUrl: boolean
set routerLink: any[]|string
set preserveQueryParams: boolean
onClick(): boolean
get urlTree: UrlTree
}Copy the code
Examples of this project:
<li class="nav-item">
<a class="nav-link" routerLink="/" routerLinkActive="active" [routerLinkActiveOptions] ="{exact: true}">The home page</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/translate" routerLinkActive="active">translation</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/search" routerLinkActive="active">search</a>
</li>Copy the code
[routerLinkActiveOptions]=”{exact: true}”. [routerLinkActiveOptions]=”{exact: true}”.
- Js writing
class Router {
constructor(rootComponentType: Type<any>|null, urlSerializer: UrlSerializer, rootContexts: ChildrenOutletContexts, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes)
get events: Observable<Event>
get routerState: RouterState
errorHandler: ErrorHandler
navigated: boolean
urlHandlingStrategy: UrlHandlingStrategy
routeReuseStrategy: RouteReuseStrategy
onSameUrlNavigation: 'reload'|'ignore'
config: Routes
initialNavigation(): void
setUpLocationChangeListener(): void
get url: string
resetConfig(config: Routes): void
ngOnDestroy(): void
dispose(): void
createUrlTree(commands: any[], navigationExtras: NavigationExtras = {}): UrlTree
navigateByUrl(url: string|UrlTree, extras: NavigationExtras = {skipLocationChange: false}) :Promise<boolean>
navigate(commands: any[], extras: NavigationExtras = {skipLocationChange: false}) :Promise<boolean>
serializeUrl(url: UrlTree): string
parseUrl(url: string): UrlTree
isActive(url: string|UrlTree, exact: boolean): boolean
}Copy the code
Examples of this project:
gotoDetail ({ entry }) {
this.router.navigate([`/detail/${entry}`])}Copy the code
Both examples are the easiest to use compared to an overview of the documentation, so you can look at other methods if you need to, and basically cover all routing requirements.
request
Unlike Vue and React, Angular provides a front-end full stack solution that includes HTTP modules and only needs to be introduced in app.module.ts
import { HttpClientModule } from '@angular/common/http'
// ...
imports: [
HttpClientModule
]
// ...Copy the code
The syntax of the request is also very simple, you can go to Github to see the code.
The ngOnInit hook does not trigger the request for update when the route is changed.
The following code
ngOnInit () {
this.route.params.subscribe((params) = > {
this.loading = true
const apiURL = `https://dict.youdao.com/jsonapi?q=${params['word']}`
this.http.get(` /? url=The ${encodeURIComponent(apiURL)}`)
.subscribe(res= > {
// set component data
this.loading = false})})}Copy the code
Invalid because there are no written before this. The route. Params. Subscribe ((params) = > {}), so every time not trigger monitor
Subscribe listens for this.route.params all the time.
Request path
As with Axios’ baseURL, we don’t want to write the full path for each request at request time, and need to configure the global baseURL to keep the request path short.
Angular needs @Injectable. Dependency injection is a familiar concept. We’ve written about it in articles
@Injectable()
export class ExampleInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const url = 'https://proxy-oagpwnbkpe.now.sh'
req = req.clone({
url: url + req.url
})
return next.handle(req)
}
}
// ...
providers: [
AppComponent,
{ provide: HTTP_INTERCEPTORS, useClass: ExampleInterceptor, multi: true}]// ...Copy the code
This code solves the baseURL problem.
Forward requests
Notice here in the previous section that const URL = ‘https://proxy-oagpwnbkpe.now.sh’, the root path is not the path to dao.
A layer of Node proxy processing is still done. Cross-domain issues still need to be addressed.
The code for the Node service is also very simple, using fly for node side requests
The following code
const express = require('express')
const fly = require('flyio')
const app = express()
app.use('/'.async (req, res) => {
const data = await fly.get(req.query.url).then(res= > res.data)
res.set('Access-Control-Allow-Origin'.The '*')
res.send(data)
})
app.listen(process.env.PORT || 3001)Copy the code
The key is to set an access-Control-allow-Origin: * in the return header so that the browser does not block the request.
The data flow
On the detail page, five subcomponents are split, and of course the parent component is a very simple one-way data flow
Example: The HTML of the parent component is as follows
<app-detail-phrs-list-tab [simple] ="simple" [ec] ="ec"></app-detail-phrs-list-tab>Copy the code
The component.ts of the child component looks like this
export class DetailPhrsListTabComponent {
@Input() simple
@Input() ec
}Copy the code
I can use @input to get the value that the parent component passed in. So how do I manage global state, depending on the complexity of the project
Simple global state management can create a global.ts and then dependency injection, as follows
// globals.ts
import { Injectable } from '@angular/core';
@Injectable()
export class Globals {
role: string = 'test';
}Copy the code
This can be called in a component
// hello.component.ts
import { Component } from '@angular/core';
import { Globals } from './globals';
@Component({
selector: 'hello'.template: 'The global role is {{globals.role}}'.providers: [Globals]
})
export class HelloComponent {
constructor(private globals: Globals) {}
}Copy the code
Another approach is the global state management libraries familiar to SPA developers, such as Flex, Redux
Angular also provides Angular-Redux, recommended for use in complex applications.
Package online
The package command provides several configuration parameters around ng build, which will not be described here.
The deployment uses surge
A word of caution: Do not deploy private projects to such public services; there are many drawbacks.
conclusion
Either front-end framework has its advantages. Since the project is small and there is no chance of unleashing the power of RXJS, angular-CLI has installed this library by default and is very efficient in handling complex asynchronous data flows.
The related documents
The documentation for this Angular 5 update is as follows
IO /docs: blog.angular. IO /version-5-0… Official CLI: github.com/angular/ang…
Go over the wall as far as you can. The domestic angular.cn/ documentation hasn’t been updated yet.