Angular学习笔记

1、环境搭建

1.1 准备全局环境

1.1.1 安装运行时环境

node.js,可到官网自行下载稳定版本。node.js只需要在开发环境中安装,无需在发布环境中安装。为什么?因为开发环境需要使用到各种各样的开发工具:如webapck、@angular/cli、sass/less等等,这些工具等运行需要node.js环境。而发布环境中,项目已经打包成原生的javascript ,html和css文件,这些文件运行在浏览器中,浏览器中已经集成了javascript运行环境,如chrome,edge,firefox,safari。

node -v

1.1.2 安装包管理工具

如果选择使用npm (node package manager),则此安装步骤可以跳过,因为在安装node.js时会顺带安装npm。除了npm,还可以选择使用yarn作为包管理工具,这里以npm为例。

npm -v

1.1.3 配置源地址

编辑~/.npmrc文件,内容如下(使用阿里的淘宝npm镜像)

registry = https://registry.npm.taobao.org

1.1.4 安装angular开发工具包 @angular/cli

npm i @angular/cli -g
ng --version

1.1.5 安装IDE

可以选择比较流行的Visual Studio Code,可到微软官网免费下载。除此还可以选择其它IDE如WebStorm、Sublime等。

1.2 准备测试项目

使用@angular/cli代码生成工具创建测试项目原型。

ng new myapp

1.3 安装项目依赖包

切换到项目根目录 myapp,运行如下命令安装项目开发框架开发工具包依赖。

npm i

1.3.1 开发框架包

根据项目功能需要选择安装,以下为angular框架常用包,除此外还有其它开发框架依赖包:如ng-zorro-and, echarts, rxjs等。

  1. @angular/core

  2. @angular/common

  3. @angular/forms

  4. @angular/compiler

  5. @angular/router

  6. @angular/animations

1.3.2 开发工具包

  1. @angular/cli

  2. @angular/compiler-cli

  3. @angular-devkit/core

  4. @angular-devkit/architect

  5. @angular-devkit/angular-builder

  6. @angular-devkit/build-optimizer

  7. @angular-devkit/build-webpack

  8. @angular-devkit/schematics

  9. typescript

  10. webpack

  11. babel等等

1.4 运行测试项目

在项目根目录myapp下如下ng serve命令,--open自动打开浏览器,--port=4500使用4500端口。serve也可以简写成s,命令简化为:

ng s

ng serve --open --port=4500

至此,angular项目开发环境搭建完毕。

 

2、项目配置

2.1 package.json

{
  "name": "myapp",
  "version": "1.0.0",
  "description": "this is my test angular app",
  "main": "index.js",
  "scripts": {
    "run": "ng serve",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "hello"
  ],
  "author": "roy",
  "license": "ISC",
  "dependencies": {
    "@angular/animations": "^12.2.4",
    "@angular/common": "^12.2.4",
    "@angular/compiler": "^12.2.4",
    "@angular/core": "^12.2.4",
    "@angular/forms": "^12.2.4",
    "@angular/platform-browser": "^12.2.4",
    "@angular/platform-browser-dynamic": "^12.2.4",
    "@angular/router": "^12.2.4",
    "rxjs": "~6.6.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^12.2.4",
    "@angular/cli": "^12.2.4",
    "@angular/compiler-cli": "^12.2.4",
    "tslint": "^6.1.3"
  }
}

配置说明

配置项配置说明配置举例
name 项目名称 myapp
version 项目版本 0.0.1
description 项目描述 this is my test project
main 项目的入口javascript文件 main.js
scripts npm命令脚本集合 { run: "ng serve", test: "echo 'hello npm' "}
keywords 项目关键字,用于发布后的搜索筛选,比如github上搜索你的项目。 ["angular", "guide"]
author 项目作者 roy
license 项目license MIT
dependencies 开发框架、类库依赖包 rxjs, echarts, @angular/core, ng-zorro-antd, zone.js等。
devDependencies 开发工具依赖包,比如一些代码生成器,编译工具,测试工具,构建工具,dev server,代码压缩工具,代码优化工具,打包工具。 @angular/cli, webpack, typescript, babel, tslint, karma, jasmine等。

包的版本配置:

版本范围约束方式解释说明举例
~a.b.c patch版本号变化,major和minor不变 ~1.2.3 表示版本号要大于等于1.2.3,但要小于1.3.0
^a.b.c minor和patch版本号变化,major不变 ^1.2.3 表示版本号要大于等于1.2.3,但要小于2.0.0

major.minor.patch

a.b.c

2.2 package-lock.json

指定了依赖包等具体版本已经下载地址。

2.3 angular.json

{
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
      "myapp": {
        "projectType": "application",
        "schematics": {
          "@schematics/angular:component": {
            "style": "scss"
          }
        },
        "root": "",
        "sourceRoot": "src",
        "prefix": "app",
        "architect": {
          "build": {},
          "serve": {},
          "extract-i18n": {},
          "test": {},
          "e2e": {}
        }
      }
    },
    "defaultProject": "myapp"
  }

配置说明

 

配置项解释说明配置举例
$schema angular.json的schema验证文件,比如可以自动填充属性或属性值  
version 项目版本  
newProjectRoot 这个属性定义了由CLI创建的新的内部应用和库放置的位置。默认值为projects projects
projects 这个属性包含了工作空间中所有项目的配置信息,一个angular工作空间可以包含多个项目。angular项目的worksapce类似vs中的solution。  
projects\ {pn} 项目名称 My app
projectType 项目类型,如application表示是一个应用程序,如library表示是一个类库项目。 application library
schematics schematics属性配置 Schematics packages  
root root属性 指定了项目文件的根文件夹,可能为空,但是它指定了一个特定的文件夹。  
sourceRoot sourceRoot指定了项目源文件位置  
prefix prefix属性 当CLI创建 component或者directive时,使用该属性 来区别他们。 app
architect angular项目的核心配置,为本项目的各个构建目标配置默认值。 常用的构建目标有:build、serve、test、lint。  
build 打包应用,对应构建器为@angular-devkit/build-angular:browser  
serve 启动应用,对应构建器为@angular-devkit/build-angular:dev-server  
test 测试应用,对应构建器为@angular-devkit/build-angular:karma  
lint 静态代码分析,类似coverity 对应构建器为@angular-devkit/build-angular:tslint  
defaultProject 默认工程,类似vs中的默认启动项目 "startup project" myapp

2.3.1 构建器

@angular/cli中的构建器,可以类比maven中的plugin插件,使用不同的plugin来完成对应的任务,如编译、测试、打包。

mvn compile
mvn test
mvn package

angular中常用的构建器有build、serve、test、lint,对应的命令如下:

ng build
ng serve
ng test
ng lint

下面对各构建器的配置做详细解释。

2.3.2 build构建器

"architect": {
  "build": {
    //build构建器所对应的npm包。
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      //打包输出位置
      "outputPath": "dist/myapp",
      //主页面
      "index": "src/index.html",
      //angular的入口ts文件。
      "main": "src/main.ts",
      //typescript配置文件。
      "tsConfig": "tsconfig.app.json",
      //是否启用预编译,true表示启用。
      "aot": true,
      //需要打包的资源文件,如图片,字体,图标等。
      "assets": [
        "src/favicon.ico",
        "src/assets"
      ],
      //需要打包的全局样式文件,会自动添加到index.html <style>标签中
      "styles": [
        "src/styles.scss",
        "./node_modules/bootstrap/dist/css/bootstrap.min.css"
      ],
      //需要打包的脚本文件,如jquery.js, bootstrap.js等。            
      //这些脚本的加载方式和在 index.html 的 <script> 标签中添加是完全一样的。
      "scripts": [              
        "./node_modules/bootstrap/dist/js/bootstrap.min.js"
      ]
    },
    //构建参数配置
    "configurations": {
      //开发环境打包配置项
      "dev":{
        "optimization": false,
        "sourceMap": true
      },
      //测试环境打包配置项
      "qa":{
        "optimization": false,
        "sourceMap": true,
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.qa.ts"
          }
        ]
      },
      //prod环境打包配置项
      "prod": {
        //需要替换的文件,可以制定多个文件。
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.prod.ts"
          }
        ],
        //是否启用js代码混淆,压缩。
        "optimization": true,
        //?
        "outputHashing": "all",
        //是否启用sourceMap, dev环境应该启动,方便调试ts文件。
        "sourceMap": false,
        "namedChunks": false,
        "extractLicenses": true,
        "vendorChunk": false,
        "buildOptimizer": true,
        "budgets": [
          {
            "type": "initial",
            "maximumWarning": "2mb",
            "maximumError": "5mb"
          },
          {
            "type": "anyComponentStyle",
            "maximumWarning": "6kb",
            "maximumError": "10kb"
          }
        ]
      }
    }
  },
  "serve": {},
  "test": {},
  "lint":{}
}

2.3.3 serve构建器

"architect": {
  "serve": {
    //serve构建器对应的npm包。
    "builder": "@angular-devkit/build-angular:dev-server",
    //应用运行配置项
    "options": {
      //引用build构建器的配置,格式为{project_name}:{builder_name}:{env}.
      //如果{evn}缺失,则使用dev环境配置。
      "browserTarget": "myapp:build:dev",
      //指定dev-server监听端口号。
      "port": 4200,
      //程序运行后是否自动打开浏览器。
      "open": false
    },
    //当然,你也可以在ng serve 中修改所使用的环境配置,通过指定 --c={env}
    //在你需要使用本地代码调试qa环境问题时,可以使用ng serve --c=qa 切换到qa环境运行。
    //例如:ng serve --c=qa
    "configurations": {
      "dev":{
        //这里无需对构建参数(如optimization,sourceMap等等)重复配置,只需要引用build构建器中配置好的环境即可。
        "browserTarget": "myapp:build:dev"
      },
      "qa":{
        "browserTarget": "myapp:build:qa"
      },
      "prod": {
        "browserTarget": "myapp:build:prod"
      }
    }
  },
  "build": {},
  "test": {},
  "lint": {}
}

2.3.4 test构建器

TODO 待续

2.3.5 lint构建器

TODO 待续

2.4 tsconfig.app.json

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  //扩张配置文件
  "extends": "./tsconfig.json",
  //tsc编译选项
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

具体配置请见《typescript学习笔记》的编译配置章节。至此,angular配置完成。

 

3、开发基础

在进行angular开发前,请学习TypeScript相关基础知识。

3.1 基础概念

3.1.1 Module

每个应用会有一个根模块,默认类名为AppModule,被放在app.module.ts文件中,应用启动时,就会加载这个模块。 每个根模块会有一个根组件,默认为类名为AppComponent,放在app.component.ts文件中,其selecor名字默认为app-root

查看项目目录中的index.html,会发现有<app-root>Loading...</app-root>这样的代码,就是在加载这个根模块。

 

3.1.2 Component

组件(component)是使用angular进行web app开发的功能单元,通常由模板、UI逻辑代码ts和样式组成。

1、html模板文件:负责页面布局和UI显示,属于View层;

2、typescript文件:负责页面UI逻辑和交互处理,属于ViewModel层;

3、样式文件:有css、sass和less三种,辅助html模板文件完成页面布局和UI显示,也属于View层;

4、model类文件:负责承接业务逻辑的计算结果数据,属于Model层。

model类文件一般在组件之间共享,不属于具体哪一个组件。

 

3.1.2.1 创建组件

以TestComponent组件的创建代码为例:

1、组件的ts代码

import { Component } from "@angular/core";
​
@Component({
  selector: "app-test",
  templateUrl: "./test.component.html",
  styleUrls: ["./test.component.scss"]
})
export class TestComponent {
  public componentName:string ="TestComponent";
  constructor(){}
  //todo
}

2、组件的模板html文件 test.component.html

<div>
  <span>This is a test component: {{componentName}}</span>
</div>

3、组件的样式文件 test.component.scss, 样式文件还可以是 test.component.css或者test.component.lcss

span {
  font-size:15px;
  color: red;
}

4、组件注册

需要将组件注册到其所在的module中,这样组件才可以对外暴露出来,被同module下的其它组件或者其它module下的组件所使用。

具体操作为:将TestComponent放置于其所在module:AppModule的装饰器@NgModule的declarations参数中,如下代码所示。

import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
​
import { AppComponent } from './app.component';
import { TestComponent } from './test/test.component';
​
@NgModule({
  declarations: [
    AppComponent,
    TestComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    CommonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { } 
3.1.2.1.1 @Component装饰器

其定义如下:

export interface Component extends Directive {
    /**
     * Defines the used change detection strategy.
     * 定义使用的变化检测策略
     * 当一个组件被实例化时, angular创建一个变更检测器, 它负责
传播组件的绑定。
     *"changeDetection" 属性的定义是, 是否每次都检查更改检测
或者只有当组件告诉什么时候去检测变化
     */
    changeDetection?: ChangeDetectionStrategy;
​
     # 定义一组只对其视图子DOM可用的可注入的对象
    viewProviders?: Provider[];
​
     # 使用 SystemJS 才用,现在一般很少使用了
    moduleId?: string;
​
    templateUrl?: string;
    template?: string;
​
    styleUrls?: string[];
    styles?: string[];
​
    # angular 动画库的一种内联写法
    animations?: any[];
​
    # 指定模版和样式封装方式,基本不用
    encapsulation?: ViewEncapsulation;
​
    # 重写默认的封装开始和结束符( `{{` and `}}`) 基本不用
    interpolation?: [string, string];
​
   # 定义其它组件在本组件被编译时,其它组件也被编译,一般用于动态插入组件的情况 用的比较多
​
    # Angular 将创建一个 {@link ComponentFactory} 并且存储在   {@link ComponentFactoryResolver}上
    entryComponents?: Array<Type<any> | any[]>;
}
​
export declare const Component: ComponentDecorator;
3.1.2.1.2 selector

组件选择器,定义了组件被引用时的标签名称,如app-nav在html页面中被引用时则表示为 <app-nav></app-nav> 。其中app前缀从配置文件中获得,当然你也可以通过修改angular.json配置文件来使用不同的标签前缀。

selector: "app-nav",

angular.json中的标签前缀配置:

"prefix": "app",
3.1.2.1.3 templateUrl

指定了组件对应的模板文件路径

templateUrl: "./nav.component.html",
3.1.2.1.4 template

如果组件对应的模板内容很少,可以将html内容直接赋给template,而不必去创建单独的html文件。注意,html内容要放在``中。

template: `<h2>{{headerText}}</h2>`

template和templateUrl两者只能选择一个。

3.1.2.1.5 styleUrls

指定了组件所使用到的样式文件路径,可以为多个。

styleUrls: ["./nav.component.scss"]
3.1.2.1.6 styles

和template对应的也有styles,当组件所需样式很少时,可以使用styles将样式直接赋给styles。

styles: `.container {color:red}`
3.1.2.1.7 encapsulation

定义了组件样式的封装方式,如下所示。默认设置为Emulated,为了防止组件样式影响其他组件,不要将encapsulation设置为None。

export declare enum ViewEncapsulation {
    /**
     * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
     * Element and pre-processing the style rules provided via {@link Component#styles styles} or
     * {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
     * selectors.
     *
     * This is the default option.
     */
    Emulated = 0,
    /**
     * Don't provide any template or style encapsulation.
     */
    None = 2,
    /**
     * Use Shadow DOM to encapsulate styles.
     *
     * For the DOM this means using modern [Shadow
     * DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) and
     * creating a ShadowRoot for Component's Host Element.
     */
    ShadowDom = 3
}

 

3.1.2.2 使用组件

组件创建后,可以被其它组件引用,获取该组件的界面和功能,从而达到界面和功能复用的目的。

如下html片段为A组件的目标内容,app-chart-box为B组件的选择器 selector。A组件引用了B组件,从而具备B组件的界面和功能。

A组件的模板html

<div>
  <app-chart-box></app-chart-box>
</div>

B组件的定义:

import { Component } from "@angular/core";
​
@Component({
  selector: "app-chart-box",
  templateUrl: "./chart-box.component.html",
  styleUrls: ["./chart-box.component.scss"]
})
export class ChartBoxComponent {
  //todo
}

 

3.1.2.3 根组件

一个Angular应用至少有一个根组件,一般命名为AppComponent,同一module中的子组件将会自动继承根组件的html模板。所以根组件一般用来创建应用程序界面布局框架,例如导航菜单、工作区div等。

通过导航切换到相应组件路由时,该组件的html内容会自动填充到<router-outlet></router-outlet>标签之中,而<router-outlet></router-outlet>以外的内容不变,从而实现框架页的功能。类似一些后端Web开发框架中的母板页,例如asp.net的master page,asp.net mvc的_layout.cshtml。

下例为一个应用程序的布局实现,在根组件中完成上下结构的布局方式,上面为导航菜单,下面为工作区。当然,你也可以根据实际需要对布局做出相应的调整,例如实现典型的左侧导航,右侧工作区的布局方式。

<div class="navContainer">
    <ul>
        <li>
            <a [routerLink]="['home']">HomeComponent</a>
        </li>
        <li>
            <a [routerLink]="['a']">AComponent</a>
        </li>
        <li>
            <a [routerLink]="['b']">BComponent</a>
        </li>
        <li>
            <a [routerLink]="['test']">TestComponent</a>
        </li>
    </ul>
</div>
<div class="wkContainer">
    <h2>individual page content comes here</h2>
    <router-outlet></router-outlet>
</div>

 

3.1.2.4 父子组件

被引用的组件为子组件,引用的组件为父组件。例如在A组件的html模板中引用了B组件的标签,则A组件是B组件的父组件,B组件是A组件的子组件。

假设B组件的selector为: app-b

A组件的html模板如下所说:

<div>
  <h1>This is A Component>
  <app-b></app-b>
</div>

 

3.1.2.5 组件间通信

组件间的通信可以分为如下几种情况:

3.1.2.5.1 子组件向父组件传值

父组件直接访问子组件的public属性;

父组件模板文件的html片段:

<app-b #child></app-b>  
<h3>
  {{child.name}}
</h3>

子组件ts文件代码片段:

public name: string = "Child Component";
3.1.2.5.2 父组件向子组件传值

使用@Output和@Input实现父组件向子组件传值

父组件:

import {Component, Output} from '@angular/core'; 
​
@Component({
  selector: "app-a",
  template: "./a.component.html",
  styleUrls: ["./a.component.scss"]
})
export class AComponent {
  @Output()
  count: number = 0;
  
  constructor(){ 
  }
  
  clickMe():void {
    this.count++;
  }
}
<p>a works!</p>
<button type="button" (click)="clickMe()">
    Click Me
</button>
<app-b [messageB] = "count"></app-b>

子组件:

import { Component, Input, OnInit } from '@angular/core';
​
@Component({
  selector: 'app-b',
  templateUrl: './b.component.html',
  styleUrls: ['./b.component.scss']
})
export class BComponent implements OnInit {
  @Input()
  public messageB:string;
​
  constructor() { }
​
  ngOnInit(): void {
  }
}
<p>b works!</p>
<h2>{{messageB}}</h2>

 

3.1.2.5.3 父组件调用子组件方法

1、父组件直接访问子组件的方法;

父组件模板文件的html片段:

<app-b #child></app-b>  
<button (click)="child.testMethod()">调用子组件方法</button>

子组件ts文件代码片段:

public name: string = "Child Component";
​
public testMethod(): void {
  console.log("method is called");
}

 

2、通过@ViewChild注解,父组件可以直接访问子组件的方法,注意一定要在ngAfterViewInit事件以后访问,否则子组件还没来得及实例化,会报空引用问题。

父组件ComponentA.ts文件代码片段:

import { AfterViewInit, Component, ViewChild } from "@angular/core";
import { ComponentB } from "../b/b.component";
​
@Component({
  selector: "app-a",
  templateUrl: "./a.component.html",
  styleUrls: ["./a.component.scss"]
})
export class ComponentA implements AfterViewInit {
  @ViewChild(ComponentB)
  private componentB: ComponentB;
​
  //直接调用B组件的方法
  public clickHandler():void {
    this.componentB.testMethod();
  }
​
  public ngAferViewInit():void {
    this.componentB.testMethod();
  }
}

父组件ComponentA的html片段

<div>
    <app-b></app-b>
    <button type="button" (click)="clickHandler()">
      Test  
    </button>
    other html for component A.
</div>

子组件ComponentB的ts代码片段

import { Component } from "@angular/core";
​
@Component({
  selector: "app-b",
  templateUrl: "./b.component.html",
  styleUrls: ["./b.component.scss"]
})
export class ComponentB {
  //直接调用B组件的方法
  public testMethod():void {
    console.log("method is called.");
  }
} 
3.1.2.5.4 父组件订阅处理子组件事件

父组件为订阅方subscriber,子组件为发布方publisher。

父组件ts代码:

import { Componet } from '@angular/core';
​
@Component({
  selector: "app-sub",
  templateUrl: "./sub.component.html",
  styleUrls: ["./sub.component.scss"]
})
export class SubComponent {
  eventData:any;
  
  onSomeEvent(data:any):void {
    this.eventData = data;
  }
}

父组件html代码:

<h2>{{eventData}}</h2>
<app-pub (someEvent)="onSomeEvent($event)"></app-pub>

通过(someEvent) = "onSomeEvent($event)"方式订阅子组件发布的事件,订阅方处理函数为onSomeEvent,参数$event为事件所传递的消息。

 

子组件ts代码:

import { Component, EventEmitter, OnInit, Output } from '@angular/core';
​
@Component({
  selector: 'app-pub',
  templateUrl: './pub.component.html',
  styleUrls: ['./pub.component.scss']
})
export class PubComponent {
  //定义事件名称
  @Output()
  someEvent = new EventEmitter<string>();
​
  constructor() { }
​
  publish(): void {
    //事件所传递消息
    let data: string = "test data from pub";
    //发布事件
    this.someEvent.emit(data);
  }
}

子组件html代码:

<button type="button" (click)="clickHandler()">Publish Event</button>

 

3.1.2.5.5 组件没有直接关系通信方式

1、借助于 Service 单例进行通讯 2、利用 cookie 和 localstorage 进行通讯 3、利用 session 进行通讯

 

3.1.3 Router

3.1.3.1 路由基本配置

配置angular路由:通常在app-routing.module.ts文件中。

import { NgModule } from '@angular/core';
import type { Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { NavComponent } from './nav/nav.component';
import { AdminComponent } from './admin/admin.component';
import { MenuAComponent } from './menu-a/menu-a.component';
​
const routes: Routes = [{
  path: "home",
  component: NavComponent
}, {
  path: "admin",
  component: AdminComponent
}, {
  path: "menuA",
  component: MenuAComponent
}];
​
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

使用路由:一般在导航组件对应的html页面中。

<ul>
  <li>
    <a [routerLink] = "['home']">Home</a>
  </li>
  <li>
    <a [routerLink]="['menuA']" target="_blank">Test Menu</a>
  </li>
  <li>
    <a [routerLink]="['admin']">Admin</a>
  </li>
</ul>

3.1.3.2 路由传值

TODO待续

3.1.4 Pipe

TODO 待续

3.1.5 Directive

TODO 待续

3.1.6 Service

TODO 待续

 

 可以使用@angular/cli的代码生成功能添加,命令如下所示。

ng generate module my-module
# generate - g
# component -c
ng g c my-component
ng g pipe my-pipe
ng g router my-router
ng g directive my-dir
ng g service my-service

3.2 Angular内置指令

3.2.1 *ngFor

<li *ngFor="let item of testArray; let i=index; let c=count;">
  {{i+1}} of {{c}}-  {{item}}
</li>
let testArray:Array<string> = ["123","abc","def","CI/CD", "Docker","K8S"];

3.2.2 *ngIf

<li *ngIf="flag">Test Item </li>
let flag:boolean = false;

3.2.3 ngClass

<h1 [ngClass]="{'testH': true}">{{envName}}</h1>
.testH {
    color:red;
}
envName:string = "";
constructor( ) {
  this.envName = environment.name;
  console.log(environment.name);
}

这里的true可以替换成表达式或者ts中定义的boolean变量。

开发基础内容较多,待续。

 

4、代码检查

4.1 ESLint配置

1、安装依赖

添加相关依赖包,在对应的package.json中的devDependencies节点内容如下:

"devDependencies": {
  "@angular-devkit/build-angular": "^12.2.4",
  "@angular-eslint/builder": "12.4.1",
  "@angular-eslint/eslint-plugin": "12.4.1",
  "@angular-eslint/eslint-plugin-template": "12.4.1",
  "@angular-eslint/schematics": "12.4.1",
  "@angular-eslint/template-parser": "12.4.1",
  "@angular/cli": "^12.2.4",
  "@angular/compiler-cli": "^12.2.4",
  "@typescript-eslint/eslint-plugin": "4.28.2",
  "@typescript-eslint/parser": "4.28.2",
  "eslint": "^7.26.0",
  "eslint-config-prettier": "^8.3.0",
  "eslint-plugin-prettier": "^4.0.0",
  "prettier": "^2.4.0",
  "prettier-eslint": "^13.0.0"
}
npm i

2、配置ESLint

在项目根目录添加.eslintrc.json文件

{
  "root": true,
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "env": {
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "rules": {
    "@typescript-eslint/consistent-type-imports": "error",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "argsIgnorePattern": "_"
      }
    ],
    "@typescript-eslint/array-type": "error"
  }
}

在angular.json中添加如下配置:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "myapp": {
      "architect": {
        "build": {},
        "serve": {},
        "lint": {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            //配置需要检查的文件pattern为src下所有的ts和html文件。
            "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
          }
        }
      }
    }
  }
}

 

5、打包部署

5.1 打包项目

一般项目开发需要准备三套环境,dev, qa, prod,不同的环境有不同的配置。Angular默认提供了dev和prod环境的配置文件,默认放在src\environments下,如下所示。

5.1.1 dev环境

// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
​
export const environment = {
  production: false,
  apiUrl: "http://localhost:12345/api/"
};
​
/*
 * For easier debugging in development mode, you can import the following file
 * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
 *
 * This import should be commented out in production mode because it will have a negative impact
 * on performance if an error is thrown.
 */
// import 'zone.js/dist/zone-error';  // Included with Angular CLI.
​

5.1.2 prod环境

export const environment = {
  production: true,
  apiUrl: "http://192.168.10.20:8080/api/"
};

5.1.3 qa环境

ng new生成的项目原型中默认没有qa环境的配置,需要自行添加,步骤如下:

步骤一:在src\environments 下新增environment.qa.ts文件,内容如下:

export const environment = {
  production: true,
  apiUrl: "http://192.168.10.19:8080/api/"
};

步骤二:修改angular.json文件,在architect\build\configuration节点下新增qa环境配置,内容如下:

"configurations": {
  "dev": {
    "optimization": false
  },
  "qa": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.qa.ts"
      }
    ]
  },
  "prod":{
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ]
  }
}

在代码中使用相应的配置,比如用于后台api访问的基地址 apiUrl。

import { Component } from '@angular/core';
import {environment} from 'src/environments/environment';
​
@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.scss']
})
export class NavComponent {
  constructor( ) {
    console.log(environment.apiUrl);
  }
}

在项目根目录如下如下命令,分别给prod, qa, dev环境打包,打包后的文件默认放在项目根目录下的dist文件夹下。

ng build --c=prod
ng build --c=qa
ng build --c=dev

5.2 部署项目

以nginx为例,将打包后的文件部署到web服务器。

5.2.1 部署准备

1、安装nginx

2、将dist下的文件拷贝至目录web服务器(使用centos),可以选择使用xManager套装中的xftp,将本地文件拷贝至服务器目标位置,比如: /data/www/myapp 。

5.2.2 部署执行

1、修改nginx配置文件,让其root指向myapp项目的发布目录 /data/www/myapp

server
{
  #监听端口
  listen 4500;
​
  #域名可以有多个,用空格隔开
  server_name xxx.com.cn;
  index index.html index.htm index.php;
  root /data/www/myapp;
  ...
}

2、启动nginx服务,访问myapp首页

cd ~/nginx/sbin
./nginx

3、如需修改conf文件,需要运行如下命令重新加载

./nginx -s reload

 至此、项目打包发布完成。

posted @ 2021-09-17 21:11  lp123  阅读(325)  评论(1编辑  收藏  举报