趁着学习Angular官方教程的同时,也学习热加载和MVVM等知识

首先

在前一篇文章中,我建立了一个基于Docker的Angular环境。
我将应用程序命名为sample-angular-on-docker。

这次我们将进行Angular官方教程中的《教程:英雄之旅》。
本教程将按照以下章节进行。

    • イントロダクション

 

    • プロジェクトの作成

 

    • 1.ヒーローエディター

 

    • 2.リストの表示

 

    • 3.フィーチャーコンポーネントの作成

 

    • 4.サービスの追加

 

    • 5.ナビゲーションの追加

 

    6.サーバーからデータの取得

基本上,我会按照教程进行操作,不会写出重复的文章。
我会将每章卡壳的地方和需要牢记的要点留作文章。

各种积分

按照本文的标题所述,在做教程的同时,我们还可以学习到很多其他的知识。以下是主要的要点。

    • [POINT] ホットリロード

 

    • [POINT] ディレクトリ構成

 

    • [POINT] 「spec」って何?

 

    • [POINT] component と service の違い

 

    [POINT] その他

[POINT] 热重载

当文件更新时,如果能够进行热重载,我会感到非常高兴。经过调查,发现只需要在启动选项中设置 –poll 参数即可。
因此,在启动时,请使用以下设置。

# こっちじゃなくて
root@60ff460a2f75:/projects/app# ng serve --host 0.0.0.0

# こっちを使う事で、ホットリロードができる
root@60ff460a2f75:/projects/app# ng serve --host 0.0.0.0 --poll 1  # 起動オプション --poll を指定

[POINT] 目录结构

项目创建后的目录结构

刚创建项目的目录结构如下。

sh
.
├── README.md
├── angular.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
├── .browserslistrc
├── .editorconfig
├── .gitignore
├── .vscode
| └── (省略)
├── node_modules
| └── (省略)
└── src
├── app
│   ├── app-routing.module.ts
│   ├── app.component.css
│   ├── app.component.html
│   ├── app.component.spec.ts
│   ├── app.component.ts
│   └── app.module.ts
├── assets
├── environments
│   ├── environment.prod.ts
│   └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
└── test.ts

教程完成后的目录结构

当你继续进行教程时会发现,每次使用Angular CLI执行组件、服务等操作时,app/目录下会生成零散的文件。

指导完成后的目录结构sh
.
├── README.md
├── angular.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
├── .browserslistrc
├── .editorconfig
├── .gitignore
├── .vscode
│ └── (省略)
├── node_modules
│ └── (省略)
└── src
├── app <—————————- app下面真是太多了!这样管理不了啊 X-(
│ ├── dashboard
│ │ ├── dashboard.component.css
│ │ ├── dashboard.component.html
│ │ ├── dashboard.component.spec.ts
│ │ └── dashboard.component.ts
│ ├── hero-detail
│ │ ├── hero-detail.component.css
│ │ ├── hero-detail.component.html
│ │ ├── hero-detail.component.spec.ts
│ │ └── hero-detail.component.ts
│ ├── hero-search
│ │ ├── hero-search.component.css
│ │ ├── hero-search.component.html
│ │ ├── hero-search.component.spec.ts
│ │ └── hero-search.component.ts
│ ├── heroes
│ │ ├── heroes.component.css
│ │ ├── heroes.component.html
│ │ ├── heroes.component.spec.ts
│ │ └── heroes.component.ts
│ ├── messages
│ │ ├── messages.component.css
│ │ ├── messages.component.html
│ │ ├── messages.component.spec.ts
│ │ └── messages.component.ts
│ ├── app-routing.module.ts
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── hero.service.spec.ts
│ ├── hero.service.ts
│ ├── hero.ts
│ ├── in-memory-data.service.spec.ts
│ ├── in-memory-data.service.ts
│ ├── message.service.spec.ts
│ ├── message.service.ts
│ └── mock-heroes.ts
├── assets
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
└── test.ts

目录结构(MVVM/最终形式)

在进行源代码管理时,目录结构非常重要,但是并没有明确的最佳实践。
如果你搜索一下,会发现以下类似的文章。

    • https://blog.lacolaco.net/2019/07/angular-ngmodule-and-directories/

 

    • https://mya-ake.com/slides/regret-angular-web-app

 

    https://mattarishitemota.com/?p=510

在教程中虽然提到了按”域名单位”或”类型单位”进行区分,但在教程阶段并不存在这样的内容。
(嗯,虽然存在,但我不想考虑)

基於MVVM架構,我們可以將Angular直接組織成目錄結構,如此一來就完成了。所以我們按照MVVM的方式組織了目錄。

MVVM 再构建的目录结构sh
.
├── README.md
├── angular.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
├── .browserslistrc
├── .editorconfig
├── .gitignore
├── .vscode
| └── (省略)
├── node_modules
| └── (省略)
└── src
├── app <—————————- 变得更加清晰明了了 🙂
│   ├── app-routing.module.ts
│   ├── app.module.ts
│ ├── view
│ │   ├── app.component.css
│ │   ├── app.component.html
│ │   ├── app.component.spec.ts
│ │   ├── app.component.ts
│ │   ├── dashboard
│ │   │   ├── dashboard.component.css
│ │   │   ├── dashboard.component.html
│ │   │   ├── dashboard.component.spec.ts
│ │   │   └── dashboard.component.ts
│ │   ├── hero-detail
│ │   │   ├── hero-detail.component.css
│ │   │   ├── hero-detail.component.html
│ │   │   ├── hero-detail.component.spec.ts
│ │   │   └── hero-detail.component.ts
│ │   ├── hero-search
│ │   │   ├── hero-search.component.css
│ │   │   ├── hero-search.component.html
│ │   │   ├── hero-search.component.spec.ts
│ │   │   └── hero-search.component.ts
│ │   ├── heroes
│ │   │   ├── heroes.component.css
│ │   │   ├── heroes.component.html
│ │   │   ├── heroes.component.spec.ts
│ │   │   └── heroes.component.ts
│ │   └── messages
│ │   ├── messages.component.css
│ │   ├── messages.component.html
│ │   ├── messages.component.spec.ts
│ │   └── messages.component.ts
│ ├── viewmodel
│ │ ├── hero.service.spec.ts
│ │ ├── hero.service.ts
│ │ ├── in-memory-data.service.spec.ts
│ │ ├── in-memory-data.service.ts
│ │ ├── message.service.spec.ts
│ │ └── message.service.ts
│   └── model
│    ├── hero.ts
│    └── mock-heroes.ts
├── assets
├── environments
│   ├── environment.prod.ts
│   └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
└── test.ts

順带一提,使用Angular CLI创建组件和服务会在app/文件夹下创建,但执行命令时也可以创建文件夹。
因此,在使用Angular CLI进行代码维护时,我认为最好是在确定文件夹结构的基础上,对执行命令进行限制来进行操作。

# これだと app/ 配下に作られるので、管理しづらい
root@c773d67c1823:/projects/app# ng generate component heroes

# これだと app/view/ 配下に作られるので、管理しやすくなる
root@c773d67c1823:/projects/app# ng generate component view/heroes

「spec」是什么意思?

使用Angular CLI生成组件和服务时,会生成一个名为xxxx.component.spec.ts的文件。

# component の生成
root@c773d67c1823:/projects/app# ng generate component heroes
Node.js version v19.0.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/releases/.

CREATE src/app/heroes/heroes.component.css (0 bytes)
CREATE src/app/heroes/heroes.component.html (21 bytes)
CREATE src/app/heroes/heroes.component.spec.ts (599 bytes)    <---------- なにこれ!!!!!!!!!!!!!!
CREATE src/app/heroes/heroes.component.ts (275 bytes)
UPDATE src/app/app.module.ts (475 bytes)

# service の生成
root@c773d67c1823:/projects/app# ng generate service hero
Node.js version v19.0.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/releases/.

CREATE src/app/hero.service.spec.ts (347 bytes)    <---------- なにこれ!!!!!!!!!!!!!!
CREATE src/app/hero.service.ts (133 bytes)

这个 xxxx.component.spec.ts 在教程中不会被使用。
不使用它,所以不明白它生成的目的是什么。

经过调查,似乎是针对单独测试执行的文件。
以下是官方网站。

    https://angular.jp/guide/testing-components-basics

组件和服务的区别

先前一直混用了组件和服务这两个词,但事实上,我并不真正了解它们的意思。

当我进行调查时,在官方网站上发现了以下内容。
请看官方网站下文。

    https://angular.jp/guide/architecture

组件定义了视图。
视图是从程序逻辑和数据中由Angular选择和更改的可变屏幕元素的集合。每个应用程序至少有一个根组件。
组件使用服务来提供与视图无直接关系的特定功能。
服务提供者可以作为依赖项被注入到组件中,以模块化和有效地实现代码的重用。

我明白了。在这里,MVVM的观点开始生效。
将服务注入到组件中,这意味着这是数据绑定的机制。

因此,组件是视图,服务相当于视图模型。

了解了View和ViewModel,那Model呢?

‘似乎 ng generate interface {name} 命令可以生成与 Model 相当的内容。在教程中,hero.ts 可能相当于它,但是由于不是通过命令而是直接创建文件,从 MVVM 的角度来看可能不太明显。’

如果尝试执行上述命令,会生成以下文件(与hero.ts具有相同的结构,所以我认为这就是一个模型)。

# interface の生成
root@c773d67c1823:/projects/app# ng generate interface model/dummy
Node.js version v19.0.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/releases/.
CREATE src/app/model/dummy.ts (27 bytes)

# ファイルの確認
root@c773d67c1823:/projects/app# cat src/app/model/dummy.ts
export interface Dummy {
}

[POINT] 其他

在推进教程的过程中,除了仅能进行表面上的理解之外,还有一些用法不太能理解的。嗯,随着开发的进行,我会逐渐适应的,所以现在只需要把它们当作“原来有这样的东西”就好了。

    • データバインディングには ngModel を用いる

ngModel を使用するには、 FormsModule のimportが必要
https://angular.jp/api/forms/NgModel

classバインディングは、以下を参照

これは特に import が必要などは書かれていない
https://angular.jp/guide/class-binding

*ngFor と *ngIf で html を操作
ルーティングは ./app/app-routing.module.ts で行われて、 を使う

完成教程

我明白了如何构建,但关键的概念和规约在教程中并没有被掌握。所以,我将参考官方网站的以下内容,继续学习。

    • Angularの概念の紹介

https://angular.jp/guide/architecture

Angularコーディングスタイルガイド

https://angular.jp/guide/styleguide

用語集

https://angular.jp/guide/glossary

广告
将在 10 秒后关闭
bannerAds