用户悟 發表於 2021-9-17 21:11:00

Angular学习笔记

<h1 class="md-end-block md-p"><span class="md-plain">1、环境搭建</span></h1>
<h2 class="md-end-block md-heading"><span class="md-plain">1.1 准备全局环境</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">1.1.1 安装运行时环境</span></h3>
<p class="md-end-block md-p"><span class="md-plain">node.js,可到官网自行下载稳定版本。node.js只需要在开发环境中安装,无需在发布环境中安装。为什么?因为开发环境需要使用到各种各样的开发工具:如webapck、@angular/cli、sass/less等等,这些工具等运行需要node.js环境。而发布环境中,项目已经打包成原生的javascript ,html和css文件,这些文件运行在浏览器中,浏览器中已经集成了javascript运行环境,如chrome,edge,firefox,safari。</span></p>
<div class="cnblogs_Highlighter">
<pre class="language-bash"><code>node -v</code></pre>
</div>
<h3 class="md-end-block md-heading"><span class="md-plain">1.1.2 安装包管理工具</span></h3>
<p class="md-end-block md-p"><span class="md-plain">如果选择使用npm (node package manager),则此安装步骤可以跳过,因为在安装node.js时会顺带安装npm。除了npm,还可以选择使用yarn作为包管理工具,这里以npm为例。</span></p>
<div class="cnblogs_Highlighter">
<pre class="language-bash"><code>npm -v</code></pre>
</div>
<h3 class="md-end-block md-heading"><span class="md-plain">1.1.3 配置源地址</span></h3>
<p class="md-end-block md-p"><span class="md-plain">编辑~/.npmrc文件,内容如下(使用阿里的淘宝npm镜像)</span></p>
<div class="cnblogs_Highlighter">
<pre class="language-bash"><code>registry = https://registry.npm.taobao.org</code></pre>
</div>
<h3 class="md-end-block md-heading"><span class="md-plain">1.1.4 安装angular开发工具包&nbsp;</span><span class="md-plain">@angular/cli</span></h3>
<div class="cnblogs_Highlighter">
<pre class="language-bash"><code>npm i @angular/cli -g
ng --version</code></pre>
</div>
<h3 class="md-end-block md-heading"><span class="md-plain">1.1.5 安装IDE</span></h3>
<p class="md-end-block md-p"><span class="md-plain">可以选择比较流行的Visual Studio Code,可到微软官网免费下载。除此还可以选择其它IDE如WebStorm、Sublime等。</span></p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.2 准备测试项目</span></h2>
<p class="md-end-block md-p"><span class="md-plain">使用@angular/cli代码生成工具创建测试项目原型。</span></p>
<pre class="language-bash"><code>ng new myapp</code></pre>
<h2 class="md-end-block md-heading"><span class="md-plain">1.3 安装项目依赖包</span></h2>
<p class="md-end-block md-p"><span class="md-plain">切换到项目根目录 myapp,运行如下命令安装项目<span class="md-pair-s "><strong>开发框架</strong><span class="md-plain">和<span class="md-pair-s "><strong>开发工具</strong><span class="md-plain">包依赖。</span></span></span></span></span></p>
<pre class="language-bash"><code>npm i</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">1.3.1 开发框架包</span></h3>
<p class="md-end-block md-p"><span class="md-plain">根据项目功能需要选择安装,以下为angular框架常用包,除此外还有其它开发框架依赖包:如ng-zorro-and, echarts, rxjs等。</span></p>
<ol class="ol-list" start="">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/core</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/common</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/forms</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/compiler</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/router</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/animations</span></p>
</li>
</ol>
<h3 class="md-end-block md-heading"><span class="md-plain">1.3.2 开发工具包</span></h3>
<ol class="ol-list" start="">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/cli</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular/compiler-cli</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular-devkit/core</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular-devkit/architect</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular-devkit/angular-builder</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular-devkit/build-optimizer</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular-devkit/build-webpack</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">@angular-devkit/schematics</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">typescript</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">webpack</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">babel等等</span></p>
</li>
</ol>
<h2 class="md-end-block md-heading"><span class="md-plain">1.4 运行测试项目</span></h2>
<p class="md-end-block md-p"><span class="md-plain">在项目根目录myapp下如下ng serve命令,--open自动打开浏览器,--port=4500使用4500端口。serve也可以简写成s,命令简化为:</span></p>
<p class="md-end-block md-p"><span class="md-plain">ng s</span></p>
<pre class="language-bash"><code>ng serve --open --port=4500</code></pre>
<p class="md-end-block md-p"><span class="md-plain">至此,angular项目开发环境搭建完毕。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h1 class="md-end-block md-heading"><span class="md-plain">2、项目配置</span></h1>
<h2 class="md-end-block md-heading"><span class="md-plain">2.1 package.json</span></h2>
<pre class="language-javascript"><code>{
"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\" &amp;&amp; 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"
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">配置说明</span></p>
<table class="md-table">
<thead>
<tr class="md-end-block"><th><span class="td-span"><span class="md-plain">配置项</span></span></th><th><span class="td-span"><span class="md-plain">配置说明</span></span></th><th><span class="td-span"><span class="md-plain">配置举例</span></span></th></tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">name</span></span></td>
<td><span class="td-span"><span class="md-plain">项目名称</span></span></td>
<td><span class="td-span"><span class="md-plain">myapp</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">version</span></span></td>
<td><span class="td-span"><span class="md-plain">项目版本</span></span></td>
<td><span class="td-span"><span class="md-plain">0.0.1</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">description</span></span></td>
<td><span class="td-span"><span class="md-plain">项目描述</span></span></td>
<td><span class="td-span"><span class="md-plain">this is my test project</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">main</span></span></td>
<td><span class="td-span"><span class="md-plain">项目的入口javascript文件</span></span></td>
<td><span class="td-span"><span class="md-plain">main.js</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">scripts</span></span></td>
<td><span class="td-span"><span class="md-plain">npm命令脚本集合</span></span></td>
<td><span class="td-span"><span class="md-plain">{ run: "ng serve", test: "echo 'hello npm' "}</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">keywords</span></span></td>
<td><span class="td-span"><span class="md-plain">项目关键字,用于发布后的搜索筛选,比如github上搜索你的项目。</span></span></td>
<td><span class="td-span"><span class="md-plain">["angular", "guide"]</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">author</span></span></td>
<td><span class="td-span"><span class="md-plain">项目作者</span></span></td>
<td><span class="td-span"><span class="md-plain">roy</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">license</span></span></td>
<td><span class="td-span"><span class="md-plain">项目license</span></span></td>
<td><span class="td-span"><span class="md-plain">MIT</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">dependencies</span></span></td>
<td><span class="td-span"><span class="md-plain">开发框架、类库依赖包</span></span></td>
<td><span class="td-span"><span class="md-plain">rxjs, echarts, @angular/core, ng-zorro-antd, zone.js等。</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">devDependencies</span></span></td>
<td><span class="td-span"><span class="md-plain">开发工具依赖包,比如一些代码生成器,编译工具,测试工具,构建工具,dev server,代码压缩工具,代码优化工具,打包工具。</span></span></td>
<td><span class="td-span"><span class="md-plain">@angular/cli, webpack, typescript, babel, tslint, karma, jasmine等。</span></span></td>
</tr>
</tbody>
</table>
<p class="md-end-block md-p"><span class="md-plain">包的版本配置:</span></p>
<table class="md-table">
<thead>
<tr class="md-end-block"><th><span class="td-span"><span class="md-plain">版本范围约束方式</span></span></th><th><span class="td-span"><span class="md-plain">解释说明</span></span></th><th><span class="td-span"><span class="md-plain">举例</span></span></th></tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">~a.b.c</span></span></td>
<td><span class="td-span"><span class="md-plain">patch版本号变化,major和minor不变</span></span></td>
<td><span class="td-span"><span class="md-plain">~1.2.3 表示版本号要大于等于1.2.3,但要小于1.3.0</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">^a.b.c</span></span></td>
<td><span class="td-span"><span class="md-plain">minor和patch版本号变化,major不变</span></span></td>
<td><span class="td-span"><span class="md-plain">^1.2.3 表示版本号要大于等于1.2.3,但要小于2.0.0</span></span></td>
</tr>
</tbody>
</table>
<p class="md-end-block md-p"><span class="md-plain">major.minor.patch</span></p>
<p class="md-end-block md-p"><span class="md-plain">a.b.c</span></p>
<h2 class="md-end-block md-heading"><span class="md-plain">2.2 package-lock.json</span></h2>
<p class="md-end-block md-p"><span class="md-plain">指定了依赖包等具体版本已经下载地址。</span></p>
<h2 class="md-end-block md-heading"><span class="md-plain">2.3 angular.json</span></h2>
<pre class="language-javascript"><code>{
    "$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"
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">配置说明</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<table class="md-table">
<thead>
<tr class="md-end-block"><th><span class="td-span"><span class="md-plain">配置项</span></span></th><th><span class="td-span"><span class="md-plain">解释说明</span></span></th><th><span class="td-span"><span class="md-plain">配置举例</span></span></th></tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">$schema</span></span></td>
<td><span class="td-span"><span class="md-plain">angular.json的schema验证文件,比如可以自动填充属性或属性值</span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">version</span></span></td>
<td><span class="td-span"><span class="md-plain">项目版本</span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">newProjectRoot</span></span></td>
<td><span class="td-span"><span class="md-plain">这个属性定义了由CLI创建的新的内部应用和库放置的位置。默认值为<span class="md-pair-s"><code>projects</code></span></span></span></td>
<td><span class="td-span"><span class="md-plain">projects</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">projects</span></span></td>
<td><span class="td-span"><span class="md-plain">这个属性包含了工作空间中所有项目的配置信息,一个angular工作空间可以包含多个项目。angular项目的worksapce类似vs中的solution。</span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">projects\ {pn}</span></span></td>
<td><span class="td-span"><span class="md-plain">项目名称</span></span></td>
<td><span class="td-span"><span class="md-plain">My app</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">projectType</span></span></td>
<td><span class="td-span"><span class="md-plain">项目类型,如application表示是一个应用程序,如library表示是一个类库项目。</span></span></td>
<td><span class="td-span"><span class="md-plain">application library</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">schematics</span></span></td>
<td><span class="td-span"><span class="md-pair-s"><code>schematics</code><span class="md-plain">属性配置 <span class="md-pair-s"><code>Schematics packages</code></span></span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">root</span></span></td>
<td><span class="td-span"><span class="md-pair-s"><code>root</code><span class="md-plain">属性 指定了项目文件的根文件夹,可能为空,但是它指定了一个特定的文件夹。</span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">sourceRoot</span></span></td>
<td><span class="td-span"><span class="md-pair-s"><code>sourceRoot</code><span class="md-plain">指定了项目源文件位置</span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">prefix</span></span></td>
<td><span class="td-span"><span class="md-pair-s"><code>prefix</code><span class="md-plain">属性 当CLI创建 <span class="md-pair-s"><code>component</code><span class="md-plain">或者<span class="md-pair-s"><code>directive</code><span class="md-plain">时,使用该属性 来区别他们。</span></span></span></span></span></span></span></td>
<td><span class="td-span"><span class="md-plain">app</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">architect</span></span></td>
<td><span class="td-span"><span class="md-plain">angular项目的核心配置,为本项目的各个构建目标配置默认值。<span class="md-br md-tag"> <span class="md-plain">常用的构建目标有:build、serve、test、lint。</span></span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-pair-s "><strong>build</strong></span></span></td>
<td><span class="td-span"><span class="md-plain">打包应用,对应构建器为<span class="md-pair-s "><strong>@angular-devkit/build-angular:browser</strong></span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-pair-s "><strong>serve</strong></span></span></td>
<td><span class="td-span"><span class="md-plain">启动应用,对应构建器为<span class="md-pair-s "><strong>@angular-devkit/build-angular:dev-server</strong></span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-pair-s "><strong>test</strong></span></span></td>
<td><span class="td-span"><span class="md-plain">测试应用,对应构建器为<span class="md-pair-s "><strong>@angular-devkit/build-angular:karma</strong></span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-pair-s "><strong>lint</strong></span></span></td>
<td><span class="td-span"><span class="md-plain">静态代码分析,类似coverity<span class="md-br md-tag"> <span class="md-plain">对应构建器为<span class="md-pair-s "><strong>@angular-devkit/build-angular:tslint</strong></span></span></span></span></span></td>
<td>&nbsp;</td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">defaultProject</span></span></td>
<td><span class="td-span"><span class="md-plain">默认工程,类似vs中的默认启动项目 "startup project"</span></span></td>
<td><span class="td-span"><span class="md-plain">myapp</span></span></td>
</tr>
</tbody>
</table>
<h3 class="md-end-block md-heading"><span class="md-plain">2.3.1 构建器</span></h3>
<p class="md-end-block md-p"><span class="md-plain">@angular/cli中的构建器,可以类比maven中的plugin插件,使用不同的plugin来完成对应的任务,如编译、测试、打包。</span></p>
<pre class="language-bash"><code>mvn compile
mvn test
mvn package</code></pre>
<p class="md-end-block md-p"><span class="md-plain">angular中常用的构建器有build、serve、test、lint,对应的命令如下:</span></p>
<pre class="language-bash"><code>ng build
ng serve
ng test
ng lint</code></pre>
<p class="md-end-block md-p"><span class="md-plain">下面对各构建器的配置做详细解释。</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">2.3.2 build构建器</span></h3>
<pre class="language-javascript"><code>"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 &lt;style&gt;标签中
      "styles": [
      "src/styles.scss",
      "./node_modules/bootstrap/dist/css/bootstrap.min.css"
      ],
      //需要打包的脚本文件,如jquery.js, bootstrap.js等。            
      //这些脚本的加载方式和在 index.html 的 &lt;script&gt; 标签中添加是完全一样的。
      "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":{}
}</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">2.3.3 serve构建器</span></h3>
<pre class="language-javascript"><code>"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": {}
}</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">2.3.4 test构建器</span></h3>
<p class="md-end-block md-p"><span class="md-plain">TODO 待续</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">2.3.5 lint构建器</span></h3>
<p class="md-end-block md-p">TODO 待续</p>
<h2 class="md-end-block md-heading"><span class="md-plain">2.4 tsconfig.app.json</span></h2>
<pre class="language-javascript"><code>/* 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"
]
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">具体配置请见《typescript学习笔记》的编译配置章节。至此,angular配置完成。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h1 class="md-end-block md-heading"><span class="md-plain">3、开发基础</span></h1>
<p class="md-end-block md-p"><span class="md-plain">在进行angular开发前,请学习TypeScript相关基础知识。</span></p>
<h2 class="md-end-block md-heading"><span class="md-plain">3.1 基础概念</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">3.1.1 Module</span></h3>
<p class="md-end-block md-p"><span class="md-plain">每个应用会有一个根模块,默认类名为AppModule,被放在<span class="md-pair-s"><code>app.module.ts</code><span class="md-plain">文件中,应用启动时,就会加载这个模块。<span class="md-softbreak"> <span class="md-plain">每个根模块会有一个根组件,默认为类名为AppComponent,放在<span class="md-pair-s"><code>app.component.ts文件中</code><span class="md-plain">,其selecor名字默认为<span class="md-pair-s"><code>app-root</code><span class="md-plain">。</span></span></span></span></span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">查看项目目录中的<span class="md-pair-s"><code>index.html</code><span class="md-plain">,会发现有<span class="md-pair-s"><code>&lt;app-root&gt;Loading...&lt;/app-root&gt;</code><span class="md-plain">这样的代码,就是在加载这个根模块。</span></span></span></span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3.1.2 Component</span></h3>
<p class="md-end-block md-p"><span class="md-plain">组件(component)是使用angular进行web app开发的功能单元,通常由模板、UI逻辑代码ts和样式组成。</span></p>
<p class="md-end-block md-p"><span class="md-plain">1、html模板文件:负责页面布局和UI显示,属于View层;</span></p>
<p class="md-end-block md-p"><span class="md-plain">2、typescript文件:负责页面UI逻辑和交互处理,属于ViewModel层;</span></p>
<p class="md-end-block md-p"><span class="md-plain">3、样式文件:有css、sass和less三种,辅助html模板文件完成页面布局和UI显示,也属于View层;</span></p>
<p class="md-end-block md-p"><span class="md-plain">4、model类文件:负责承接业务逻辑的计算结果数据,属于Model层。</span></p>
<p class="md-end-block md-p"><span class="md-plain">model类文件一般在组件之间共享,不属于具体哪一个组件。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h4 class="md-end-block md-heading"><span class="md-plain">3.1.2.1 创建组件</span></h4>
<p class="md-end-block md-p"><span class="md-plain">以TestComponent组件的创建代码为例:</span></p>
<p class="md-end-block md-p"><span class="md-plain">1、组件的ts代码</span></p>
<pre class="language-javascript"><code>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
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">2、组件的模板html文件 test.component.html</span></p>
<pre class="language-html"><code>&lt;div&gt;
&lt;span&gt;This is a test component: {{componentName}}&lt;/span&gt;
&lt;/div&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">3、组件的样式文件 <span class="md-pair-s "><strong>test.component.scss</strong><span class="md-plain">, 样式文件还可以是 test.component.css或者test.component.lcss</span></span></span></p>
<pre class="language-css"><code>span {
font-size:15px;
color: red;
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">4、组件注册</span></p>
<p class="md-end-block md-p"><span class="md-plain">需要将组件注册到其所在的module中,这样组件才可以对外暴露出来,被同module下的其它组件或者其它module下的组件所使用。</span></p>
<p class="md-end-block md-p"><span class="md-plain">具体操作为:将TestComponent放置于其所在module:AppModule的装饰器@NgModule的<span class="md-pair-s"><strong>declarations</strong><span class="md-plain">参数中,如下代码所示。</span></span></span></p>
<pre class="language-javascript"><code>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:
})
export class AppModule { }</code>&nbsp;</pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.1 @Component装饰器</span></h5>
<p class="md-end-block md-p"><span class="md-plain">其定义如下:</span></p>
<pre class="language-javascript"><code>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?: ;

   # 定义其它组件在本组件被编译时,其它组件也被编译,一般用于动态插入组件的情况 用的比较多

    # Angular 将创建一个 {@link ComponentFactory} 并且存储在   {@link ComponentFactoryResolver}上
    entryComponents?: Array&lt;Type&lt;any&gt; | any[]&gt;;
}

export declare const Component: ComponentDecorator;</code></pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.2&nbsp;</span><span class="md-plain">selector</span></h5>
<p class="md-end-block md-p"><span class="md-plain">组件选择器,定义了组件被引用时的标签名称,如app-nav在html页面中被引用时则表示为 <span class="md-pair-s"><strong><span class="md-tag md-raw-inline">&lt;app-nav&gt;<span class="md-tag md-raw-inline">&lt;/app-nav&gt;</span></span></strong><span class="md-plain"> 。其中app前缀从配置文件中获得,当然你也可以通过修改angular.json配置文件来使用不同的标签前缀。</span></span></span></p>
<pre class="language-javascript"><code>selector: "app-nav",</code></pre>
<p class="md-end-block md-p"><span class="md-plain">angular.json中的标签前缀配置:</span></p>
<pre class="language-javascript"><code>"prefix": "app",</code></pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.3 templateUrl</span></h5>
<p class="md-end-block md-p"><span class="md-plain">指定了组件对应的模板文件路径</span></p>
<pre class="language-javascript"><code>templateUrl: "./nav.component.html",</code></pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.4 template</span></h5>
<p class="md-end-block md-p"><span class="md-plain">如果组件对应的模板内容很少,可以将html内容直接赋给template,而不必去创建单独的html文件。注意,html内容要放在``中。</span></p>
<pre class="language-javascript"><code>template: `&lt;h2&gt;{{headerText}}&lt;/h2&gt;`</code></pre>
<p class="md-end-block md-p"><span class="md-plain">template和templateUrl两者只能选择一个。</span></p>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.5 styleUrls</span></h5>
<p class="md-end-block md-p"><span class="md-plain">指定了组件所使用到的样式文件路径,可以为多个。</span></p>
<pre class="language-javascript"><code>styleUrls: ["./nav.component.scss"]</code></pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.6 styles</span></h5>
<p class="md-end-block md-p"><span class="md-plain">和template对应的也有styles,当组件所需样式很少时,可以使用styles将样式直接赋给styles。</span></p>
<pre class="language-javascript"><code>styles: `.container {color:red}`</code></pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.1.7 encapsulation</span></h5>
<p class="md-end-block md-p"><span class="md-plain">定义了组件样式的封装方式,如下所示。默认设置为Emulated,为了防止组件样式影响其他组件,不要将encapsulation设置为None。</span></p>
<pre class="language-javascript"><code>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
}</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h4 class="md-end-block md-heading"><span class="md-plain">3.1.2.2 使用组件</span></h4>
<p class="md-end-block md-p"><span class="md-plain">组件创建后,可以被其它组件引用,获取该组件的界面和功能,从而达到界面和功能复用的目的。</span></p>
<p class="md-end-block md-p"><span class="md-plain">如下html片段为A组件的目标内容,app-chart-box为B组件的选择器 selector。A组件引用了B组件,从而具备B组件的界面和功能。</span></p>
<p class="md-end-block md-p"><span class="md-plain">A组件的模板html</span></p>
<pre class="language-html"><code>&lt;div&gt;
&lt;app-chart-box&gt;&lt;/app-chart-box&gt;
&lt;/div&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">B组件的定义:</span></p>
<pre class="language-javascript"><code>import { Component } from "@angular/core";

@Component({
selector: "app-chart-box",
templateUrl: "./chart-box.component.html",
styleUrls: ["./chart-box.component.scss"]
})
export class ChartBoxComponent {
//todo
}</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h4 class="md-end-block md-heading"><span class="md-plain">3.1.2.3 根组件</span></h4>
<p class="md-end-block md-p"><span class="md-plain">一个Angular应用至少有一个根组件,一般命名为AppComponent,同一module中的子组件将会自动继承根组件的html模板。所以根组件一般用来创建应用程序界面布局框架,例如导航菜单、工作区div等。</span></p>
<p class="md-end-block md-p"><span class="md-plain">通过导航切换到相应组件路由时,该组件的html内容会自动填充到<span class="md-tag md-raw-inline">&lt;router-outlet&gt;<span class="md-tag md-raw-inline">&lt;/router-outlet&gt;<span class="md-plain">标签之中,而<span class="md-tag md-raw-inline">&lt;router-outlet&gt;<span class="md-tag md-raw-inline">&lt;/router-outlet&gt;<span class="md-plain">以外的内容不变,从而实现框架页的功能。类似一些后端Web开发框架中的母板页,例如asp.net的master page,asp.net mvc的_layout.cshtml。</span></span></span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">下例为一个应用程序的布局实现,在根组件中完成上下结构的布局方式,上面为导航菜单,下面为工作区。当然,你也可以根据实际需要对布局做出相应的调整,例如实现典型的左侧导航,右侧工作区的布局方式。</span></p>
<pre class="language-html"><code>&lt;div class="navContainer"&gt;
    &lt;ul&gt;
      &lt;li&gt;
            &lt;a ="['home']"&gt;HomeComponent&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
            &lt;a ="['a']"&gt;AComponent&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
            &lt;a ="['b']"&gt;BComponent&lt;/a&gt;
      &lt;/li&gt;
      &lt;li&gt;
            &lt;a ="['test']"&gt;TestComponent&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
&lt;div class="wkContainer"&gt;
    &lt;h2&gt;individual page content comes here&lt;/h2&gt;
    &lt;router-outlet&gt;&lt;/router-outlet&gt;
&lt;/div&gt;</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h4 class="md-end-block md-heading"><span class="md-plain">3.1.2.4 父子组件</span></h4>
<p class="md-end-block md-p"><span class="md-plain">被引用的组件为子组件,引用的组件为父组件。例如在A组件的html模板中引用了B组件的标签,则A组件是B组件的父组件,B组件是A组件的子组件。</span></p>
<p class="md-end-block md-p"><span class="md-plain">假设B组件的selector为: app-b</span></p>
<p class="md-end-block md-p"><span class="md-plain">A组件的html模板如下所说:</span></p>
<pre class="language-html"><code>&lt;div&gt;
&lt;h1&gt;This is A Component&gt;
&lt;app-b&gt;&lt;/app-b&gt;
&lt;/div&gt;</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h4 class="md-end-block md-heading"><span class="md-plain">3.1.2.5 组件间通信</span></h4>
<p class="md-end-block md-p"><span class="md-plain">组件间的通信可以分为如下几种情况:</span></p>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.5.1 子组件向父组件传值</span></h5>
<p class="md-end-block md-p"><span class="md-plain">父组件直接访问子组件的public属性;</span></p>
<p class="md-end-block md-p"><span class="md-plain">父组件模板文件的html片段:</span></p>
<pre class="language-html"><code>&lt;app-b #child&gt;&lt;/app-b&gt;
&lt;h3&gt;
{{child.name}}
&lt;/h3&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">子组件ts文件代码片段:</span></p>
<pre class="language-javascript"><code>public name: string = "Child Component";</code></pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.5.2 父组件向子组件传值</span></h5>
<p class="md-end-block md-p"><span class="md-plain">使用@Output和@Input实现父组件向子组件传值</span></p>
<p class="md-end-block md-p"><span class="md-plain">父组件:</span></p>
<pre class="language-javascript"><code>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++;
}
}</code></pre>
<pre class="language-html"><code>&lt;p&gt;a works!&lt;/p&gt;
&lt;button type="button" (click)="clickMe()"&gt;
    Click Me
&lt;/button&gt;
&lt;app-b = "count"&gt;&lt;/app-b&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">子组件:</span></p>
<pre class="language-javascript"><code>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 {
}
}</code></pre>
<pre class="language-html"><code>&lt;p&gt;b works!&lt;/p&gt;
&lt;h2&gt;{{messageB}}&lt;/h2&gt;</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.5.3 父组件调用子组件方法</span></h5>
<p class="md-end-block md-p"><span class="md-plain">1、父组件直接访问子组件的方法;</span></p>
<p class="md-end-block md-p"><span class="md-plain">父组件模板文件的html片段:</span></p>
<pre class="language-html"><code>&lt;app-b #child&gt;&lt;/app-b&gt;
&lt;button (click)="child.testMethod()"&gt;调用子组件方法&lt;/button&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">子组件ts文件代码片段:</span></p>
<pre class="language-javascript"><code>public name: string = "Child Component";

public testMethod(): void {
console.log("method is called");
}</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">2、通过@ViewChild注解,父组件可以直接访问子组件的方法,注意一定要在ngAfterViewInit事件以后访问,否则子组件还没来得及实例化,会报空引用问题。</span></p>
<p class="md-end-block md-p"><span class="md-plain">父组件ComponentA.ts文件代码片段:</span></p>
<pre class="language-javascript"><code>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();
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">父组件ComponentA的html片段</span></p>
<pre class="language-html"><code>&lt;div&gt;
    &lt;app-b&gt;&lt;/app-b&gt;
    &lt;button type="button" (click)="clickHandler()"&gt;
      Test
    &lt;/button&gt;
    other html for component A.
&lt;/div&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">子组件ComponentB的ts代码片段</span></p>
<pre class="language-javascript"><code>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.");
}
}</code>&nbsp;</pre>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.5.4 父组件订阅处理子组件事件</span></h5>
<p class="md-end-block md-p"><span class="md-plain">父组件为订阅方subscriber,子组件为发布方publisher。</span></p>
<p class="md-end-block md-p"><span class="md-plain">父组件ts代码:</span></p>
<pre class="language-javascript"><code>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;
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">父组件html代码:</span></p>
<pre class="language-html"><code>&lt;h2&gt;{{eventData}}&lt;/h2&gt;
&lt;app-pub (someEvent)="onSomeEvent($event)"&gt;&lt;/app-pub&gt;</code></pre>
<p class="md-end-block md-p"><span class="md-plain">通过(someEvent) = "onSomeEvent($event)"方式订阅子组件发布的事件,订阅方处理函数为onSomeEvent,参数$event为事件所传递的消息。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">子组件ts代码:</span></p>
<pre class="language-javascript"><code>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&lt;string&gt;();

constructor() { }

publish(): void {
    //事件所传递消息
    let data: string = "test data from pub";
    //发布事件
    this.someEvent.emit(data);
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">子组件html代码:</span></p>
<pre class="language-html"><code>&lt;button type="button" (click)="clickHandler()"&gt;Publish Event&lt;/button&gt;</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h5 class="md-end-block md-heading"><span class="md-plain">3.1.2.5.5 组件没有直接关系通信方式</span></h5>
<p class="md-end-block md-p"><span class="md-plain">1、借助于 Service 单例进行通讯<span class="md-softbreak"> <span class="md-plain">2、利用 cookie 和 localstorage 进行通讯<span class="md-softbreak"> <span class="md-plain">3、利用 session 进行通讯</span></span></span></span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3.1.3 Router</span></h3>
<h4 class="md-end-block md-p"><span class="md-plain">3.1.3.1 路由基本配置</span></h4>
<p class="md-end-block md-p"><span class="md-plain">配置angular路由:通常在app-routing.module.ts文件中。</span></p>
<pre class="language-javascript"><code>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: ,
exports:
})
export class AppRoutingModule { }</code></pre>
<p class="md-end-block md-p"><span class="md-plain">使用路由:一般在导航组件对应的html页面中。</span></p>
<pre class="language-html"><code>&lt;ul&gt;
&lt;li&gt;
    &lt;a = "['home']"&gt;Home&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
    &lt;a ="['menuA']" target="_blank"&gt;Test Menu&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
    &lt;a ="['admin']"&gt;Admin&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;<br></code></pre>
<h4 class="md-end-block md-p"><span class="md-plain">3.1.3.2 路由传值</span></h4>
<p><span class="md-plain">TODO待续</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">3.1.4 Pipe</span></h3>
<p>TODO 待续</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3.1.5 Directive</span></h3>
<p>TODO 待续</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3.1.6 Service</span></h3>
<p>TODO 待续</p>
<p>&nbsp;</p>
<p class="md-end-block md-p">&nbsp;<span class="md-plain">可以使用@angular/cli的代码生成功能添加,命令如下所示。</span></p>
<pre class="language-bash"><code>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</code></pre>
<h2 class="md-end-block md-heading"><span class="md-plain">3.2 Angular内置指令</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">3.2.1 *ngFor</span></h3>
<pre class="language-html"><code>&lt;li *ngFor="let item of testArray; let i=index; let c=count;"&gt;
{{i+1}} of {{c}}-{{item}}
&lt;/li&gt;</code></pre>
<pre class="language-javascript"><code>let testArray:Array&lt;string&gt; = ["123","abc","def","CI/CD", "Docker","K8S"];</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">3.2.2 *ngIf</span></h3>
<pre class="language-html"><code>&lt;li *ngIf="flag"&gt;Test Item &lt;/li&gt;</code></pre>
<pre class="language-javascript"><code>let flag:boolean = false;</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">3.2.3 ngClass</span></h3>
<pre class="language-html"><code>&lt;h1 ="{'testH': true}"&gt;{{envName}}&lt;/h1&gt;</code></pre>
<pre class="language-css"><code>.testH {
    color:red;
}</code></pre>
<pre class="language-javascript"><code>envName:string = "";
constructor( ) {
this.envName = environment.name;
console.log(environment.name);
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">这里的true可以替换成表达式或者ts中定义的boolean变量。</span></p>
<p class="md-end-block md-p"><span class="md-plain">开发基础内容较多,待续。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h1 class="md-end-block md-heading"><span class="md-plain">4、代码检查</span></h1>
<h2 class="md-end-block md-heading"><span class="md-plain">4.1 ESLint配置</span></h2>
<p class="md-end-block md-p"><span class="md-plain">1、安装依赖</span></p>
<p class="md-end-block md-p"><span class="md-plain">添加相关依赖包,在对应的package.json中的devDependencies节点内容如下:</span></p>
<pre class="language-javascript"><code>"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"
}</code></pre>
<pre class="language-bash"><code>npm i</code></pre>
<p class="md-end-block md-p"><span class="md-plain">2、配置ESLint</span></p>
<p class="md-end-block md-p"><span class="md-plain">在项目根目录添加.eslintrc.json文件</span></p>
<pre class="language-javascript"><code>{
"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"
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">在angular.json中添加如下配置:</span></p>
<pre class="language-javascript"><code>{
"$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"]
          }
      }
      }
    }
}
}</code></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h1 class="md-end-block md-heading"><span class="md-plain">5、打包部署</span></h1>
<h2 class="md-end-block md-heading"><span class="md-plain">5.1 打包项目</span></h2>
<p class="md-end-block md-p"><span class="md-plain">一般项目开发需要准备三套环境,dev, qa, prod,不同的环境有不同的配置。Angular默认提供了dev和prod环境的配置文件,默认放在src\environments下,如下所示。</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">5.1.1 dev环境</span></h3>
<pre class="language-javascript"><code>// 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.
​</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">5.1.2 prod环境</span></h3>
<pre class="language-javascript"><code>export const environment = {
production: true,
apiUrl: "http://192.168.10.20:8080/api/"
};</code></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">5.1.3 qa环境</span></h3>
<p class="md-end-block md-p"><span class="md-plain">ng new生成的项目原型中默认没有qa环境的配置,需要自行添加,步骤如下:</span></p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>步骤一</strong><span class="md-plain">:在src\environments 下新增environment.qa.ts文件,内容如下:</span></span></p>
<pre class="language-javascript"><code>export const environment = {
production: true,
apiUrl: "http://192.168.10.19:8080/api/"
};</code></pre>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>步骤二</strong><span class="md-plain">:修改angular.json文件,在architect\build\configuration节点下新增qa环境配置,内容如下:</span></span></p>
<pre class="language-javascript"><code>"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"
      }
    ]
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">在代码中使用相应的配置,比如用于后台api访问的基地址 apiUrl。</span></p>
<pre class="language-javascript"><code>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);
}
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">在项目根目录如下如下命令,分别给prod, qa, dev环境打包,打包后的文件默认放在项目根目录下的dist文件夹下。</span></p>
<pre class="language-bash"><code>ng build --c=prod</code></pre>
<pre class="language-bash"><code>ng build --c=qa</code></pre>
<pre class="language-bash"><code>ng build --c=dev</code></pre>
<h2 class="md-end-block md-heading"><span class="md-plain">5.2 部署项目</span></h2>
<p class="md-end-block md-p"><span class="md-plain">以nginx为例,将打包后的文件部署到web服务器。</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">5.2.1 部署准备</span></h3>
<p class="md-end-block md-p"><span class="md-plain">1、安装nginx</span></p>
<p class="md-end-block md-p"><span class="md-plain">2、将dist下的文件拷贝至目录web服务器(使用centos),可以选择使用xManager套装中的xftp,将本地文件拷贝至服务器目标位置,比如: /data/www/myapp 。</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">5.2.2 部署执行</span></h3>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">1、修改nginx配置文件,让其root指向myapp项目的发布目录 /data/www/myapp</span></p>
<pre class="language-nginx"><code>server
{
#监听端口
listen 4500;

#域名可以有多个,用空格隔开
server_name xxx.com.cn;
index index.html index.htm index.php;
root /data/www/myapp;
...
}</code></pre>
<p class="md-end-block md-p"><span class="md-plain">2、启动nginx服务,访问myapp首页</span></p>
<pre class="language-bash"><code>cd ~/nginx/sbin
./nginx</code></pre>
<p class="md-end-block md-p"><span class="md-plain">3、如需修改conf文件,需要运行如下命令重新加载</span></p>
<pre class="language-bash"><code>./nginx -s reload</code></pre>
<p>&nbsp;至此、项目打包发布完成。</p><br><br>
来源:https://www.cnblogs.com/Roy_Zhou/p/15306314.html
頁: [1]
查看完整版本: Angular学习笔记