配置开发环境

开发工具

  • Node.js
  • VS Code / WebStorm

搭建Nexus NPM私服

概念和配置方法与Maven私服相同,分为proxy、hosted、group三类。
创建proxy如下:
Angular学习笔记_第1张图片
Remote URL: https://registry.npmjs.org
hosted、group创建方法不再赘述。创建完毕后在home下创建.npmrc文件,其内填写group地址,如下:
registry=http://localhost:8081/repository/npm-public/

NPM

Angular 8,Node.js版本要求10.9.0或以上。
RHEL、CentOS、Fedora执行如下命令安装:

$ curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -
$ sudo yum -y install nodejs

查看nodejs、npm版本:

node -v
npm -v

更新npm:

npm i npm@latest -g

NPM帮助

npm help
npm -l 列出所有命令用法
npm  -h 查看某一命令用法,如:
npm ls -h
npm help npm 在浏览器中查看帮助文档,如:
npm help index (Index of all npm documentation)
npm help folders
npm help install

Angular项目创建后,可运行以下命令查看package版本信息:
npm ls 列出所有package
npm view [package] 查看package发布的版本,如:
npm view ng-zorro-antd versions 列出所有ng-zorro-antd版本
npm view ng-zorro-antd 查看最新ng-zorro-antd版本信息
npm view [email protected] 查看[email protected]版本信息
进入node_modules/package目录下,运行npm version可查看安装的版本。

Angular CLI

安装Angular CLI

npm install -g @angular/cli@latest

注意:要用@latest
更新Angular CLI
Global package:

npm uninstall -g @angular/cli
npm cache verify
npm install -g @angular/cli@latest

Local project package:

# use rmdir /S/Q node_modules in Windows Command Prompt
# use rm -r -fo node_modules in Windows PowerShell
rm -rf node_modules
npm install --save-dev @angular/cli@latest
npm install

ng帮助

ng help 显示所有命令的帮助
ng [command name] --help  显示某一命令的帮助
ng add  Add support for a library to your project
ng new  [options] Creates a new directory and a new Angular app
ng generate  [options] Generates and/or modifies files based on a schematic
ng update  [options] Updates your application and its dependencies
ng build  [options] Builds your app and places it into the output path (dist/ by default)
ng serve  [options] Builds and serves your app, rebuilding on file changes
ng test  [options] Run unit tests in existing project
ng e2e  [options] Run e2e tests in existing project

常用参数:
--aot Build using Ahead of Time compilation
--base-href Base url for the application being built
--i18n-file Localization file to use for i18n
--prod Flag to set configuration to "prod"

Available schematics:

  • serviceWorker
  • application
  • class
  • component
  • directive
  • enum
  • guard
  • interface
  • module
  • pipe
  • service
  • universal
  • appShell
  • library

更新package

Angular每6个月发布一个主版本,可运行ng update更新package。
ng update
在Project根目录下运行ng update会显示需要更新的package,可以选择更新部分或全部package。

ng update
    We analyzed your package.json, there are some packages to update:

      Name                               Version                  Command to update
     --------------------------------------------------------------------------------
      @angular/cli                       6.2.8 -> 8.0.2           ng update @angular/cli
      @angular/core                      6.1.10 -> 8.0.0          ng update @angular/core
      @angular/core                      6.1.10 -> 7.2.15         ng update @angular/core
      rxjs                               6.3.3 -> 6.5.2           ng update rxjs

    There might be additional packages that are outdated.
    Or run ng update --all to try to update all at the same time.

package.json中的version语法请参见The semantic versioner for npm
npm update

npm update

npm-check-updates

  • 安装npm-check-updates
    npm i -g npm-check-updates
  • 升级
    ncu -u
  • 安装新版本
    npm install

Angular新功能

Angular 5.0

  • 编译性能提升,AOT编译速度加快,开发中推荐使用
  • i18n支持新的number、 date、 currency pipes
  • 使用StaticInjector替代ReflectiveInjector,不再需要Reflect polyfill,减少app大小。
  • exportAs支持多个名字
  • @angular/http模块已过期,推荐使用HttpClient
  • 新增Router Lifecycle Events
    GuardsCheckStart, ChildActivationStart, ActivationStart, GuardsCheckEnd, ResolveStart, ResolveEnd, ActivationEnd, ChildActivationEnd
  • 语法检查更严格

Angular 6.0

  • CLI Workspaces
    CLI v6支持包含多项目的workspace,使用angular.json代替了.angular-cli.json。
  • Angular CLI更新
    新增ng add、ng update、ng generate library
    ng add  Add support for a library to your project
    ng update  [options] Updates your application and its dependencies
    ng generate library  create a library project within your CLI workspace
  • Tree Shakable Providers
    从module引用服务改为服务引用模块,使得应用更小。

之前:

@NgModule({
  ...
  providers: [MyService]
})
export class AppModule {}
import { Injectable } from '@angular/core';

@Injectable()
export class MyService {
  constructor() { }
}

现在:

import { Injectable } from '@angular/core';

@Injectable({providedIn: 'root'})
export class MyService {
  constructor() { }
}
  • Angular Material Starter Components
    运行ng add @angular/material,生成3个新的starter component:
    Material Sidenav
    Angular学习笔记_第2张图片
    Material Dashboard
    Angular学习笔记_第3张图片
    Material Data Table
    Angular学习笔记_第4张图片
  • Animations Performance Improvements
  • RxJS v6

UI组件

推荐开源UI组件:ag-Grid、Amexio、Angular Material、NG-ZORRO。

  • ag-Grid(The best Javascript grid in the world)
    数据表格组件,支持排序、筛选、编辑、选择、分组、聚合、旋转等许多强大的功能和操作

  • Amexio

    1. 130+ UI组件
    2. 支持拖拽
    3. 响应式网页设计
    4. 57个主题
    5. 支持图表、地图、仪表盘
  • Angular Material
    Angular官方组件库,提供表单控件、导航、布局、按钮、弹出窗口、数据表格等组件。

  • NG-ZORRO
    阿里出品的企业级UI组件,设计完全兼容并遵守Ant Design规范,会与Ant Design React版本保持功能同步。NG-ZORRO符合国人使用习惯,国内用户较多。

NG-ZORRO

  1. 初始化配置

进入项目文件夹,执行以下命令将自动完成ng-zorro-antd的初始化配置,包括引入国际化文件,导入模块,引入样式文件等

ng add ng-zorro-antd
  1. 定制主题

初始化项目时,运行ng add ng-zorro-antd --theme 会自动配置主题文件src/theme.less,编辑文件即可自定义主题。样式使用了Less作为开发语言。

  1. 代码演示

NG-ZORRO使用简单,文档、示例代码全面,摘录示例代码如下:
表单

import { Component, OnInit } from '@angular/core';
import {
  AbstractControl,
  FormBuilder,
  FormGroup,
  Validators
} from '@angular/forms';

@Component({
  selector: 'nz-demo-form-normal-login',
  template: `
    
  `,
  styles: [ `
    .login-form {
      max-width: 300px;
    }

    .login-form-forgot {
      float: right;
    }

    .login-form-button {
      width: 100%;
    }
  `
  ]
})
export class NzDemoFormNormalLoginComponent implements OnInit {
  validateForm: FormGroup;

  submitForm(): void {
    for (const i in this.validateForm.controls) {
      this.validateForm.controls[ i ].markAsDirty();
      this.validateForm.controls[ i ].updateValueAndValidity();
    }
  }

  constructor(private fb: FormBuilder) {
  }

  ngOnInit(): void {
    this.validateForm = this.fb.group({
      userName: [ null, [ Validators.required ] ],
      password: [ null, [ Validators.required ] ],
      remember: [ true ]
    });
  }
}

效果图:
Angular学习笔记_第5张图片

  1. NG-ZORRO Table

使用push或splice修改nzData的数据不会生效,需如下操作:

// 增加数据
this.dataSet = [ ...this.dataSet, {
  key    : `${this.i}`,
  name   : `Edward King ${this.i}`,
  age    : '32',
  address: `London, Park Lane no. ${this.i}`
}];
// 删除数据
this.dataSet = this.dataSet.filter(d => d.key !== i);
  1. 测试

注意,在angular.json的test部分也要引入样式和SVG icon资源。

"test": {
  ...
    "styles": [
      "src/theme.less",
      "src/styles.css"
    ],
    "assets": [
      ...
      {
        "glob": "**/*",
        "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
        "output": "/assets/"
      }
    ]
  }
}

使用NG-ZORRO组件的页面,需导入BrowserAnimationsModule和NgZorroAntdModule:

TestBed.configureTestingModule({
     imports: [
       BrowserAnimationsModule,
       NgZorroAntdModule
     ]
})

定制组件

演示如何定制NG-ZORRO Pagination组件。
page.components.ts

import {Component, EventEmitter, Input, Output} from '@angular/core';
import {DEFAULT_PAGE_SIZE} from '../../model/page';

@Component({
  selector: 'app-page',
  templateUrl: './page.component.html'
})

export class PageComponent {
  @Input()
  total: number;

  @Input()
  pageIndex: number;

  @Input()
  pageSize = DEFAULT_PAGE_SIZE;

  pageSizeOptions = [10, 20, 30, 40];

  @Output()
  pageChange: EventEmitter = new EventEmitter();

  indexChange(index: any) {
    this.pageChange.emit({'pageIndex': index, 'pageSize': this.pageSize});
  }

  sizeChange(size: any) {
    this.pageChange.emit({'pageIndex': 1, 'pageSize': size});
  }
}

page.components.html

Total {{total}} items

页面调用

...
pageChanged(event: any): void {
  this.getHeroes(event.pageIndex - 1, event.pageSize);
}

getHeroes(page: number, size: number): void {
  this.heroService.searchHeroes(this.query, {page: page, size: size})
    .subscribe(data => {
      this.heroes = data.content;
      this.totalItems = data.totalElements;
    });
}
...

分页查询

下面是Spring Boot项目中常用的分页查询方法:

@ApiOperation("Find heroes")
@GetMapping("/heroes")
public Page searchHeroes(Hero hero,
                               @SortDefault.SortDefaults({@SortDefault(sort = "name", direction = Sort.Direction.DESC)}) @ApiIgnore Pageable pageable) {
    return service.findHeroes(hero, pageable);
}

在Angualr中如何封装Page、Pageable、查询参数呢?示例如下:

import {HttpParams} from '@angular/common/http';

export const DEFAULT_PAGE_SIZE = 10;

export interface Page {
  content: T[];
  totalPages: number;
  totalElements: number;
}

export interface Pageable {
  page: number;
  size: number;
  sorts?: { key: string, value: string }[];
}

export function pageParams(query?: T, pageable?: Pageable): HttpParams {
  let params = new HttpParams()
    .set('page', pageable ? pageable.page.toString() : '0')
    .set('size', pageable ? pageable.size.toString() : DEFAULT_PAGE_SIZE.toString());

  if (pageable) {
    for (const sort of pageable.sorts) {
      params = params.set('sort', sort.value === 'ascend' ? `${sort.key},ASC` : `${sort.key},DESC`);
    }
  }

  if (query) {
    Object.keys(query).forEach(key => {
      let value = query[key];
      if (!value) {
        return;
      }
      if (value instanceof Date) {
        value = value.toISOString();
      }
      params = params.set(key, value);
    });
  }

  return params;
}

注意,HttpParams是不可变的,封装查询参数时,如下写法是错误的:

let params = new HttpParams();
params.set('page', page.toString())
params.set('size', "10");

Service调用HttpClient的get方法执行分页查询:

...
this.http.get('url', { pageParams(query, pageable) })
...

ExcelJS

ExcelJS是读写XLSX和CSV格式文件的开源组件,MIT License。相对于SheetJS组件,ExcelJS更容易设置Excel样式。
安装ExcelJS:

npm install --save exceljs

ExcelJS写文件需使用FileSaver.js:

npm install --save file-saver

然后在tsconfig.json中添加:

"paths": {
  "exceljs": [
    "node_modules/exceljs/dist/exceljs.js",
    "node_modules/file-saver/dist/FileSaver.js"
  ]
}

使用示例:

import {Workbook} from 'exceljs';
import * as fs from 'file-saver';

...
  const workBook = new Workbook();
  const workSheet = workBook.addWorksheet('Sheet1');
  workSheet.columns = [
    {header: 'ID', key: 'id', width: 12},
    {header: 'Name', key: 'name', width: 12},
    {header: 'Email', key: 'email', width: 50}
  ];

    var rows = [
    {id:1, name: 'Jason', email: '[email protected]'},
        {id:2, name: 'Coco', email: '[email protected]'}
    ];
    worksheet.addRows(rows);

  workSheet.getRow(1).eachCell((cell, colNumber) => {
    cell.fill = {type: 'pattern', pattern: 'solid', fgColor: {argb: 'FF00CCFF'}, bgColor: {argb: 'FFFFFF00'}};
    cell.font = {bold: true};
  });
  workSheet.getColumn('email').alignment = { vertical: 'bottom', horizontal: 'left' };

  workBook.xlsx.writeBuffer().then(value => {
    const blob = new Blob([value], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
    fs.saveAs(blob, 'test');
  });
...

CKEditor 4

开源WYSIWYG HTML编辑器,支持GPL, LGPL, MPL协议。用法如下:

  1. Include CKEditor javascript files in your application
  1. Install ng2-ckeditor
npm install --save ng2-ckeditor

3.Include CKEditorModule in your main module

import { CKEditorModule } from 'ng2-ckeditor';

@NgModule({
  // ...
  imports:      [
    CKEditorModule
  ],
  // ...
})
export class AppModule { }
  1. usage

学习资料

Angular
TypeScript
TypeScript中文网
NPM Docs
RxJS
NG-ZORRO
CKEditor Ecosystem
Angular HTTP Client - Quickstart Guide
Angular Architecture - Smart Components vs Presentational Components