学习Angular有一段时间了,把学习到的东西记录下来,以便忘记了能重新复习
一、学习网站
-
HTML、CSS、JavaScript文档学习网站: https://www.runoob.com/
-
angular官网:https://angular.cn/.
可以看完基础知识后,学习并实践“英雄列表”的项目,加深记忆和了解: link.
-
typescript学习:https://www.tslang.cn/docs/release-notes/typescript-3.1.html
二、UI开源库
三、常用工具
四、开发环境
-
安装全局 Angular Cli,只有这样才能随时随地在终端使用
ng
命令,可以通过终端窗口中运行:npm install -g @angular/cli
五、VSCode 扩展
- Debugger for Chrome: 调试Angular代码
- Angular Extension Pack: 集成了很多提升Angular开发效率的插件
- Chinese (Simplified) Language Pack for Visual Studio Code:适用于 VS Code 的中文(简体)语言包
- NG-ZORRO Snippets: NG-ZORRO标签自动补齐工具
- Git Tags: git版本库的一个标记,指向某个commit的指针
- gitignore: git软件要忽略的文件列表. 如果要忽略某些文件,在Git工作区的根目录下创建一个特殊的.
六、常用命令(基于NG-ALAIN)
-
新建项目
ng new my-project --style less --routing
-
新建模块
ng g ng-alain:module my-module
-
生成组件
ng g component my-component
-
创建服务
ng g service services/my-services
-
创建pip
ng g pipe pipe/my-pipe
-
创建gard
ng g guard my-guard
-
启动项目
ng s (默认端口4200,需更改端口则加上 --port 端口)
-
构建应用程序,打包
ng build
七、基本使用
-
angular三种括号
(): 事件绑定
[]: 属性绑定
{{}}: 数据绑定
// html <button nz-button [nzType]="'primary'" (click)="showModal()" class="btn-add" [disabled]="!isOperation"> 新增 </button>
-
表达式
使用表达式把数据绑定到HTML,写在双大括号内:
{{ expression }}
。// html {{ expression }} {{ num * num }} {{ role.name }}
// typescript expression = '一周不见,如隔七天。' num = 7; role = { name: '东皇太一般', gender: '男', age: 1 };
-
数据绑定
NgModel
使用
NgModel
指令显示数据属性,并在用户进行更改时更新该属性。// html <nz-select [(ngModel)]="selectedValue"> <nz-option nzValue="培根芝士饭团" nzLabel="培根芝士饭团"></nz-option> <nz-option nzValue="豆腐肥牛卷" nzLabel="豆腐肥牛卷"></nz-option> <nz-option nzValue="青瓜小卷" nzLabel="青瓜小卷"></nz-option> </nz-select>
// typescript selectedValue = 'lucy';
-
元素显示
NgIf
通过将
NgIf
指令应用于宿主元素来添加或删除元素。// html <p *ngIf="content">唱得很好,下次不准再唱了</p>
// typescript content = false;
-
条目列表
NgFor
使用
NgFor
来指令显示条目列表。// html <ul> <li *ngFor="let item of items">{{ item }}</li> </ul>
// typescript items = ['关你西红柿','虾仁不眨眼','悲伤猪大肠','快乐鸡蛋黄'];
可以获取
*ngFor
的index
,并在模板中使用它。// html <ul> <li *ngFor="let item of items; let i = index">{{ i + 1 }} - {{ item }}</li> </ul>
-
管道
管道
用来对字符串、货币金额、日期和其他显示数据进行转换和格式化。DatePipe
:根据本地环境中的规则格式化日期值。UpperCasePipe
:把文本全部转换成大写。LowerCasePipe
:把文本全部转换成小写。CurrencyPipe
:把数字转换成货币字符串,根据本地环境中的规则进行格式化。DecimalPipe
:把数字转换成带小数点的字符串,根据本地环境中的规则进行格式化。PercentPipe
:把数字转换成百分比字符串,根据本地环境中的规则进行格式化。- 自定义
// html {{ 'Tony带水' | uppercase }} {{ today | date }} {{ today | date: 'yyyy-MM-dd HH:mm:ss' }}
// typescript today = new Date();
-
事件绑定
(click)
点击事件// html <button nz-button nzType="primary" (click)="test()">
// typescript test(): void { console.log('别叫我达芬奇 让我唱首Melody'); }
-
路由配置
-
路由参数:
1、path:一个用于匹配浏览器地址栏中URL的字符串
2、component:当导航到此路由时,设置ULR指向一个组件
const routes: Routes = [{ path: 'to-do-list', component: ToDoListComponent }];
-
路由跳转
constructor(private router: Router) {} ...... this.router.navigate(['/to-do-list']);
-
在路由路径中传递参数
http://localhost:4200/#/workplace/route/1
// 在路由进行配置 { path: 'to-do-list/:id',component:ToDoListComponent}
// html <a [routerLink]="['/workplace/route', 1]">route/1</a>
// 接收参数 constructor(private routerInfo: ActivatedRoute) {} ...... this.id = this.routerInfo.snapshot.params['id'];
-
在查询参数中传递参数
http://localhost:4200/#/workplace/route-new?name=煎妮
// 在路由进行配置 { path: 'route-new', component: RouteNewComponent }
// html <li><a [routerLink]="['/workplace/route-new']" [queryParams]="{ name: '煎妮' }">route-new</a></li>
// 接收参数 constructor(private routerInfo: ActivatedRoute) {} ...... this.name = this.routerInfo.snapshot.queryParams['name'];
八、Demo
-
新建一个名为
training
的Angular项目ng new training --style less --routing
-
当提示
Packages installed successfully.
表示创建成功,接下来只需要将 NG-ALAIN 添加到training
项目中即可,在training
目录下通过终端窗口中运行:ng add ng-alain
-
添加
ng-zorro
ng add ng-zorro-antd
-
启动完成后会打开浏览器访问 http://localhost:4200
-
新建一个名为
workplace
的Module,位于src/app/routes
下E:\training> ng g ng-alain:module workplace
src\app\routes\routes-routing.module.ts 下也添加了如下信息:
{ path: 'workplace', loadChildren: () => import('./workplace/workplace.module').then(m => m.WorkplaceModule) }
-
新建一个名为
to-do-list
的component,位于workplace
下E:\training> ng g component routes/workplace/to-do-list
-
配置路由
-
在
workplace-routing.module.ts
里添加以下信息const routes: Routes = [{ path: 'to-do-list', component: ToDoListComponent }];
-
在
workplace.module.ts
里添加以下信息const COMPONENTS: Array<Type<void>> = [ToDoListComponent]; @NgModule({ imports: [SharedModule, CommonModule, WorkplaceRoutingModule], declarations: COMPONENTS })
-
在
src\app\core\startup\startup.service.ts
里添加以下信息this.menuService.add([ { text: 'Main', group: true, children: [ { text: 'Dashboard', link: '/dashboard', icon: { type: 'icon', value: 'appstore' } }, // --------------------以下为新增------------------------- { text: 'WorkPlace', icon: { type: 'icon', value: 'appstore' }, children: [ { text: 'to-do-list', link: '/workplace/to-do-list' } ] } // --------------------以上为新增------------------------- ] } ]);
-
-
期望能做如下的效果
1.选择右上角下拉框,改变显示值(ngModel)
<ng-template #extraTemplate>
<p>今天必须完成的是:</p>
<nz-select [(ngModel)]="model" style="width: 200px">
<nz-option *ngFor="let item of todoData" [nzValue]="item.name" [nzLabel]="item.name"></nz-option>
</nz-select>
</ng-template>
2.遍历出列表信息(ngFor)
// 部分有删减样式代码
<div nz-row *ngFor="let item of todoData">
<div nz-col [nzSpan]="2" class="text-center">
<nz-avatar [nzSrc]="'./assets/tmp/img/' + item.avatar + '.png'"></nz-avatar>
</div>
<div nz-col [nzSpan]="20">
<strong>{{ item.name }}</strong>
<p>{{ item.content }}</p>
</div>
</div>
3.点击右侧“三点”图标(click),显示列表的数据 (ng-if)
<ul nz-menu>
<li nz-menu-item *ngIf="item.completed" (click)="item.completed = false">Active</li>
<li nz-menu-item *ngIf="!item.completed" (click)="item.completed = true">Completed</li>
<li nz-menu-item (click)="todoData.splice(todoData.indexOf(item), 1)">Delted</li>
</ul>
- 完整代码如下:to-do-list.component.html
<div nz-col nzLg="16">
<nz-card nzTitle="Todo list" [nzBordered]="false" class="ant-card__body-nopadding" [nzExtra]="extraTemplate">
<div nz-row [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point" *ngFor="let item of todoData">
<div nz-col [nzSpan]="2" class="text-center">
<nz-avatar [nzSrc]="'./assets/tmp/img/' + item.avatar + '.png'"></nz-avatar>
</div>
<div nz-col [nzSpan]="20">
<strong>{{ item.name }}</strong>
<p [class.text-deleted]="item.completed" class="mb0">{{ item.content }}</p>
</div>
<div nz-col [nzSpan]="2" class="text-right pr-md">
<i nz-dropdown [nzDropdownMenu]="todoMenus" nzPlacement="topRight" nz-icon nzType="ellipsis" class="rotate-90"></i>
<nz-dropdown-menu #todoMenus="nzDropdownMenu">
<ul nz-menu>
<li nz-menu-item *ngIf="item.completed" (click)="item.completed = false">Active</li>
<li nz-menu-item *ngIf="!item.completed" (click)="item.completed = true">Completed</li>
<li nz-menu-item (click)="todoData.splice(todoData.indexOf(item), 1)">Delted</li>
</ul>
</nz-dropdown-menu>
</div>
</div>
<ng-template #extraTemplate>
<p>今天必须完成的是:</p>
<nz-select [(ngModel)]="model" style="width: 200px">
<nz-option *ngFor="let item of todoData" [nzValue]="item.name" [nzLabel]="item.name"></nz-option>
</nz-select>
</ng-template>
</nz-card>
<nz-card>
<p>选择了--- {{ model }}</p>
</nz-card>
</div>
-
to-do-list.component.ts
model: string = '学习'; todoData = [ { completed: false, avatar: '1', name: '学习', content: `在知识的海洋里,我居然是条淡水鱼` }, { completed: false, avatar: '2', name: '出门', content: `健身卡办了5个月了,一斤没瘦,是时候亲自去健身房看看哪里出了问题` }, { completed: false, avatar: '3', name: '起床', content: `正义都能迟到,我为什么不能多睡十分钟` }, { completed: false, avatar: '4', name: '聊天', content: `我觉得我还挺会哄女孩睡觉的 一句在吗 她们就说要睡了` }, { completed: true, avatar: '5', name: '吃饭', content: `今晚月色可真好,想吃麦辣鸡腿堡` }, { completed: false, avatar: '6', name: '旅游', content: `放假了,买个地球仪吧,世界那么大,可以转转` } ];
九、常用方法
- 去重
// 方法一
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
const res1 = Array.from(new Set(arr));
// => [1, '1', 17, true, false, 'true', 'a', {}, {}]
// 方法二 [...new Set(array)]
let arr = [3, 5, 2, 2, 5, 5];
let unique = [...new Set(arr)];
// 字符串去重
[...new Set('ababbc')].join('')
// "abc"
- 把数组拼成字符串,用","隔开
changeArr(arr: any[], parm: string): string {
let value = '';
arr.forEach(el => {
value += el[parm] + ';';
});
return value.substr(0, value.length - 1);
}
13. 字符串截取
// 截取两个字符串之间的内容
var str = "aaabbbfff";
str = str.match(/aaa(\S*)fff/)[1];
alert(str);
// bbb
// 截取某个字符串前面的内容:
var str = "aaafff";
str = str.match(/(\S*)fff/)[1];
alert(str);
// aaa
// 截取某个字符串后面的内容:
var str = "aaafff";
str = str.match(/aaa(\S*)/)[1];
alert(str);
// fff
14. 判断是否为空的方法
noEmpty(obj: any): boolean {
const regu = '^[ ]+$';
const re = new RegExp(regu);
if (typeof obj === 'undefined' || obj == null || obj === '' || re.test(obj)) {
return false;
} else {
return true;
}
}
- 两个数组拼成数组对象
let arr1 = ['一π胡言', '有bear来', '半tour废'];
let arr2 = [true, false, false];
let arr3 = arr1.map((label, i) => ({ label, checked: arr2[i] }));
- 两个数组拼成对象
let arr_key = ['age', 'name', 'gender'];
let arr_value = ['1', '孙尚香菜', '女'];
for (let i in arr_key) {
this.obj1[arr_key[i]] = arr_value[i];
}
- 箭头函数的简写
// a). 省略小括号,当形参有且只有一个的时候
let add = (n) => { return n+n; }
let add = n => { return n+n; }
// b). 省略花括号,当代码体只有一条语句的时候,而且语句的执行结果就是函数的返回值
let pow = (n) => { return n*n; }
let pow = (n) => n*n;
- 扩展运算符的应用
// 数组的合并
const arr1 = [1, 2];
const arr2 = [3, 4];
const test = […arr1, …arr2];
// 数组的克隆
const arr1 = [1, 2, 3, 4, 5];
const arr2 = […arr1];
- 限制变量只能为固定某个值
const gender:"male" | "female";
-
限制变量类型
let a: boolean | string;
-
Array 对象方法
-
map(): 返回数组中的元素为原始数组元素调用函数处理后的值。不对空数组进行检测,不会改变原始数组
let arr = [4, 9, 16, 25]; let arr1 = arr.map(el => el * 2); let arr2 = arr.map(el => Math.sqrt(el));
-
some():检测数组是否满足条件,有一个满足返回true,剩余不再检测,没有满足条件返回false. 不改变原数组
const checkOptions = [ { label: '一π胡言', value: '一π胡言', checked: true }, { label: '有bear来', value: '有bear来', checked: false }, { label: '半tour废', value: '半tour废', checked: false } ]; let someValue = checkOptions.some(el => el.checked === false);
-
every():用于检测数组所有元素是否都符合指定条件
const checkOptions = [ { label: '一π胡言', value: '一π胡言', checked: true }, { label: '有bear来', value: '有bear来', checked: false }, { label: '半tour废', value: '半tour废', checked: false } ]; let everyValue = checkOptions.every(el => el.checked === false);
-
filter():创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
const checkOptions = [ { label: '一π胡言', value: '一π胡言', checked: true }, { label: '有bear来', value: '有bear来', checked: false }, { label: '半tour废', value: '半tour废', checked: false } ]; const arr = checkOptions.filter(el => el.checked === false);
-
reduce():方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
let num1 = [0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr);
-
find():方法返回通过测试(函数内判断)的数组的第一个元素的值。
let obj = this.checkOptions.find(el => el.checked === false);
-
join():join() 方法用于把数组中的所有元素转换一个字符串
let newString5 = arr.join(',');
-
十、可能遇到的问题及解决办法
-
网页收藏
Vue报错 “TypeError: Cannot read property ‘content’ of undefined”
Angular执行测试报错: ‘app-messages’ is not a known element
js中map()、some()、every()、filter()的区别
运用localStorage存储获取操作记录(ng-zorro)
Angular ng-zorro 读取Excel表格的内容显示在页面
Angular学习笔记45:响应式表单-FormArray & 动态的增加、减少FormArray中的元素 & 给FormArray 赋值
angular6打包时报错 ERROR in src\app\user.component.html(14,31): : Expected 1 arguments, but got 0
-
ng-zorro 自适应宽度大小
[nzXs] <576px
[nzSm] ≥576px
[nzMd] ≥768px
[nzLg] ≥992px
[nzXl] ≥1200px
[nzXXl] ≥1600px
-
调用API常遇到的错误
200: ‘服务器成功返回请求的数据。’,
201: ‘新建或修改数据成功。’,
202: ‘一个请求已经进入后台排队(异步任务)。’,
204: ‘删除数据成功。’,
400: ‘发出的请求有错误,服务器没有进行新建或修改数据的操作。’,
401: ‘用户没有权限(令牌、用户名、密码错误)。’,
403: ‘用户得到授权,但是访问是被禁止的。’,
404: ‘发出的请求针对的是不存在的记录,服务器没有进行操作。’,
406: ‘请求的格式不可得。’,
410: ‘请求的资源被永久删除,且不会再得到的。’,
422: ‘当创建一个对象时,发生一个验证错误。’,
500: ‘服务器发生错误,请检查服务器。’,
502: ‘网关错误。’,
503: ‘服务不可用,服务器暂时过载或维护。’,
504: ‘网关超时。’,
400
查看控制台信息,未可知错误里会有详细错误信息。参数错误 The JSON value could not be converted to System.Boolean
解决:存了string格式的“FALSE”,故参数类型不匹配
Object reference not set to an instance of an object
传参有问题
405
API是POST,前端写方法写了GET
Ng-zorro: 表格内的按钮、链接无法点击
设置了nz-col nzOffset=“4” nzSpan=“19”,但没在外层嵌套z-row。嵌套后即可点击