Windows下安装
install node
https://nodejs.org
C:\xxx\Downloads\node-v20.10.0-x64
C:\Program Files\nodejs\
C:\angular>node -v
v20.10.0
C:\angular>npm -v
10.2.3
install angualr
npm install -g @angular/cli
error
# 设置淘宝源
npm config set registry https://registry.npm.taobao.org
npm config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass
# 恢复默认源
npm config delete registry
npm config delete sass_binary_site
C:\angular>npm install -g @angular/cli
added 227 packages in 16s
npm notice
npm notice New patch version of npm available! 10.2.3 -> 10.2.5
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.5
npm notice Run npm install -g npm@10.2.5 to update!
npm notice
linux下安装类似
install node
https://nodejs.org/en/download/
Latest LTS Version: 20.10.0 (includes npm 10.2.3)
https://github.com/nodejs/help/wiki/Installation
1.Unzip the binary archive to any directory you wanna install Node, I use /usr/local/lib/nodejs
node-v20.10.0-linux-x64.tar.xz
VERSION=v20.10.0
DISTRO=linux-x64
mkdir -p /home/user/soft/nodejs --注意放到本地目录,别放到usr目录,否则权限麻烦
tar -xJvf node-$VERSION-$DISTRO.tar.xz -C /home/user/soft/nodejs
2.Set the environment variable ~/.bashrc, add below to the end
# Nodejs
VERSION=v20.10.0
DISTRO=linux-x64
export PATH=/home/user/soft/nodejs/node-$VERSION-$DISTRO/bin:$PATH
3.Test installation using
$ node -v
$ npm version
$ npx -v
install angular
在用户根目录下面.npmrc里面设置一下
registry=https://registry.npm.taobao.org/
同时设置一下代理--内网才需要设置
proxy=http://user:pass@proxyserver:80/
https-proxy=http://user:pass@proxyserver:80/
或者直接通过命令行设置
npm config set registry https://registry.npm.taobao.org/
npm config set proxy http://user:pass@proxyServer:80/
这样不行,被node 的教程搞错了,重新把node安装到本地目录才行
npm install -g @angular/cli
~]$ npm install -g @angular/cli
ng new angular-tour-of-heroes --no-standalone --routing --ssr=false
cd angular-tour-of-heroes
ng serve --open
修改显示:
打开 app.component.ts,并把 title 属性的值修改为 'Tour of Heroes'(英雄之旅)。
title = 'Tour of Heroes';
打开 app.component.html 并清空 ng new 创建的默认模板。改为下列 HTML 内容。
<h1>{{title}}</h1>
双花括号语法是 Angular 的插值绑定语法。这个插值绑定的意思是把组件的 title 属性的值绑定到
添加应用样式
大多数应用都会努力让整个应用保持一致的外观。ng new 会生成一个空白的 styles.css 文件。你可以把全应用级别的样式放进去。
创建英雄列表组件
ng generate component heroes
ng generate 创建了一个新的文件夹 src/app/heroes/,并生成了 HeroesComponent 的四个文件。
添加 hero 属性
hero = 'Windstorm';
显示英雄
<h2>{{hero}}</h2>
显示 HeroesComponent 视图
要显示 HeroesComponent 你必须把它加到壳组件 AppComponent 的模板中。
src/app/app.component.html:
<h1>{{title}}</h1>
<app-heroes></app-heroes>
遇到linux的一个坑:增加了heroes组件后,突然浏览器打不开了,检查发现node报错了:
Error: ENOSPC: System limit for number of file watchers reached, watch styles.css
https://zhuanlan.zhihu.com/p/599156184
inotify 是 Linux 内核 2.6.13 (June 18, 2005) 版本新增的一个子系统(API),它提供了一种监控文件系统(基于 inode 的)事件的机制,可以监控文件系统的变化如文件修改、新增、删除等,并可以将相应的事件通知给应用程序
heroes]$ grep INOTIFY_USER /boot/config-$(uname -r)
CONFIG_INOTIFY_USER=y
输出 CONFIG_INOTIFY_USER=y,代表当前系统支持 Inotify 机制
查看 Inotify 在内核中的默认配置。
-heroes]$ sysctl fs.inotify
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 512
fs.inotify.max_user_watches = 8192
方法一:增加 inotify watchers 的上限数量(临时)
heroes]$ sudo sysctl fs.inotify.max_user_watches=524288
fs.inotify.max_user_watches = 524288
heroes]$ sudo sysctl -p
fs.inotify.max_user_instances = 512
net.core.rmem_max = 52428800
net.core.wmem_max = 157286400
net.ipv4.udp_mem = 1519128 2025508 3038256
net.core.netdev_max_backlog = 20000
heroes]$ cat /proc/sys/fs/inotify/max_user_watches
524288
修改后重新运行ng serve --open 就不再报错了
方法二:增加 inotify watchers 的上限数量(永久)
heroes]$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
fs.inotify.max_user_watches=524288
heroes]$ sudo sysctl -p
fs.inotify.max_user_instances = 512
net.core.rmem_max = 52428800
net.core.wmem_max = 157286400
net.ipv4.udp_mem = 1519128 2025508 3038256
net.core.netdev_max_backlog = 20000
fs.inotify.max_user_watches = 524288
heroes]$ cat /proc/sys/fs/inotify/max_user_watches
524288
接口类:创建 Hero 类
src/app/hero.ts
export interface Hero {
id: number;
name: string;
}
heroes组件中加入Hero对象
hero: Hero = {
id: 1,
name: 'Windstorm'
};
这样界面显示就有问题了:
[object Object]
显示 hero 对象
<h2>{{hero.name}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div><span>name: </span>{{hero.name}}</div>
修改后显示正常。
管道
<h2>{{hero.name | uppercase}} Details</h2>
双向绑定
编辑英雄名字
用户应该能在一个 <input> 输入框中编辑英雄的名字。
<div>
<label for="name">Hero name: </label>
<input id="name" [(ngModel)]="hero.name" placeholder="name">
</div>
[(ngModel)] 是 Angular 的双向数据绑定语法。数据流可以双向流动。数据可以从 hero.name 属性流动到 textbox,也可以从 textbox 流回到 hero.name。
加上ngModel后,界面提示错误:
NG8002: Can't bind to 'ngModel' since it isn't a known property of 'input'.
src/app/heroes/heroes.component.html:5:21
nodejs控制台也报错,更加清晰:
⠹ Changes detected. Rebuilding...
✘ [ERROR] NG8002: Can't bind to 'ngModel' since it isn't a known property of 'input'. [plugin angular-compiler]
src/app/heroes/heroes.component.html:5:21:
5 │ <input id="name" [(ngModel)]="hero.name" placeholder="name">
╵ ~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component HeroesComponent.
src/app/heroes/heroes.component.ts:6:15:
6 │ templateUrl: './heroes.component.html',
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~
说明无法解析input的属性ngModel,它属于一个可选模块 FormsModule,你必须自行添加此模块才能使用该指令。
AppModule
Angular 需要知道如何把应用程序的各个部分组合到一起,以及该应用需要哪些其它文件和库。这些信息被称为元数据(metadata)。
有些元数据位于 @Component 装饰器中,你会把它加到组件类上。另一些关键性的元数据位于 @NgModule 装饰器中。
最重要的 @NgModule 装饰器位于顶层类 AppModule 上。
ng new 在创建项目的时候就在 src/app/app.module.ts 中创建了一个 AppModule 类。这里也就是你要添加 FormsModule 的地方。
导入 FormsModule
打开 app.module.ts 并从 @angular/forms 库中导入 FormsModule 符号。
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
然后把 FormsModule 添加到 @NgModule 的 imports 数组中,这里是该应用所需外部模块的列表。
imports: [
BrowserModule,
FormsModule
], 加上后显示不报错了,但是输入内容,标题的名字不跟着修改,后来重启了nodejs后正常了,名字可以跟着input同步变化,这是nodejs新版本的变更?
显示英雄列表
创建模拟(mock)的英雄数据
<ul>
<li *ngFor="let hero of heroes">
<button>
<span>{{hero.id}}</span>
<span>{{hero.name}}</span>
</button>
</li>
</ul>
*ngFor 是一个 Angular 的复写器(repeater)指令。它会为列表中的每项数据复写它的宿主元素。
给英雄列表“美容”
当 ng generate 创建 HeroesComponent 时,它也同时为 HeroesComponent 创建了空白的 heroes.component.css 样式表文件,并且让 @Component.styleUrls 指向它,
添加 click 事件绑定
<li *ngFor="let hero of heroes">
<button type="button" (click)="onSelect(hero)">
<!-- ... -->
这是 Angular 事件绑定 语法的例子。click 外面的圆括号会让 Angular 监听这个 <button> 元素的 click 事件。 当用户点击 <button> 时,Angular 就会执行表达式 onSelect(hero)。
添加 click 事件处理器
添加如下 onSelect() 方法,它会把模板中被点击的英雄赋值给组件的 selectedHero 属性
selectedHero?: Hero;
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
添加详情区
现在,组件的模板中有一个列表。要想在点击列表中英雄的名字时显示该英雄的详情,就要在模板中添加一个区域,用来显示这些详情。
<div *ngIf="selectedHero">
<h2>{{selectedHero.name | uppercase}} Details</h2>
<div>id: {{selectedHero.id}}</div>
<div>
<label for="hero-name">Hero name: </label>
<input id="hero-name" [(ngModel)]="selectedHero.name" placeholder="name">
</div>
</div>
为选定的英雄设置样式
为了标出选定的英雄,你可以在以前添加过的样式中增加 CSS 类 .selected。若要把 .selected 类应用于此 <li> 上,请使用类绑定。
Angular 的类绑定可以有条件地添加和删除 CSS 类。只需将 [class.some-css-class]="some-condition" 添加到要设置样式的元素即可。
在 HeroesComponent 模板中的 <button> 元素上添加 [class.selected] 绑定,代码如下:
[class.selected]="hero === selectedHero"
如果当前行的英雄和 selectedHero 相同,Angular 就会添加 CSS 类 selected,否则就会移除它。
<li *ngFor="let hero of heroes">
<button [class.selected]="hero === selectedHero" type="button" (click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span>
<span class="name">{{hero.name}}</span>
</button>
</li>
组件拆分,组件间靠Input传递参数
把英雄详情移入一个独立的、可复用的 HeroDetailComponent。最终将:
-HeroesComponent 用来展示英雄列表。
-HeroDetailComponent 用来展示所选英雄的详情。
创建组件
ng generate component hero-detail
编写模板
<div *ngIf="hero">
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label for="hero-name">Hero name: </label>
<input id="hero-name" [(ngModel)]="hero.name" placeholder="name">
</div>
</div>
添加 @Input() hero 属性
hero 属性必须是一个带有 @Input() 装饰器的输入属性,因为外部的 HeroesComponent 组件会绑定到它。就像这样:
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
修改 @angular/core 的导入语句,导入 Input 符号
import { Component, Input } from '@angular/core';
添加一个带有 @Input() 装饰器的 hero 属性
@Input() hero?: Hero;