核心知识:模块、组件、模板、指令、数据绑定、服务和依赖注入、路由
一、模块
(ng 中,模块指的是项目中功能模块,是一个抽象的概念,把功能划分出来,如商品模块,用户模块等。)
NG 中的模块叫做 NgModule,与 ES 和 node.js 中‘模块’概念不同。
ES 和 node.js 模块,一个文件就是一个模块,可以导出内部成员,引用其他模块的成员。NG 中的模块指项目中的 功能模块。
主组件的作用
引导加载模块的流程
二、组件
(组件是一块可重复使用的页面区域,有专有的样式、模块、数据,表现上就是一个自定义标签)
在 login.ts 文件中
- 导入核心,为了能够使用装饰器
import {Component} from '@angular/core'
- 导出组件对象
export class Login{ }
- 写装饰器
@Component({ //装饰器,相当于给Login贴上工牌
selector:'my-login',
template:'<h3>我的第一个angular组件</h3><br>'
})
// 上面的代码都是描述Login这个组件的数据,那么上面每个数据都叫做元数据
在 app.Module.ts 中
-
组件必须去主模块声明一下 app.Module.ts
4.1 导入子组件
import { Login } from './login';
4.2 注册
@NgModule({
declarations: [
AppComponent,
Login
], ... })
在 app.component.html 中
5.使用自定义组件 app.component.html 中
<my-login></my-login>
三、数据绑定
angular 数据绑定
VueJS 数据绑定
m--v: 插值表达式
{{}}
{{}}
m--v: 属性绑定
[src]=
v-bind: :src
v--m: 事件绑定
(click)
v-on @click='delect'
双向绑定
[(value)]
v-model:value
数据绑定
import {Component} from '@angular/core'
@Component({
selector:'emp-info',
template:`
<h3>员工信息</h3>
<div>员工姓名:{{emp.ename}}</div>
<div>员工姓名:{{emp.ename.toUpperCase()}}</div>
<div>员工姓名:{{emp.ename.toUpperCase().slice(2)}}</div>
<div>员工薪资:{{'¥'+emp.salary*12}}</div>
<div>员工性别:{{emp.gender==1 ? '男':'女'}}</div>
<div>员工生日:{{emp.birthdate}}</div>
<div>员工项目:{{emp.projectList}}</div>
<ul>
<li>{{emp.projectList[0]}}</li>
<li>{{emp.projectList[1]}}</li>
<li>{{emp.projectList[2]}}</li>
</ul>
// <div>{{emp}}</div>
// vuejs 中这种写法,会自动转换成 json 字符串
// ng 不能自动转 ng 是 [Object Object]
// <div>{{JSON.stringify(emp)}}</div>
// <div>{{new Date(emp.birthdate).getFullYear())}}</div>
// <div>{{parseInt(123.456))}}</div>
// 插值表达式中不能使用任何全局对象
`
})
export class EmpInfo{
num = 12.5;
emp={
ename:'lilei',
gender:1,
salary:10000,
birthdate:1501234567890,
projectList:['项目1','项目2','项目3']
};
showInfo() {
console.log('调用了showInfo()');
return '123';
}
}
重点知识:
{{}}插值表达式,与vuejs的不通用
-
不能使用关键字new new Date
-
不能使用全局函数 parseInt
-
不能使用全局对象 window、json
四、指令
Vuejs 提供13个指令
v-for、v-if、v-else-if、v-else、v-show
v-bind:/:、v-on:/@
v-html、v-text、v-cloak
v-once v-pre
v-model
angular中的指令分为三类(common 自动导包、forms 和 router 自行导包)
- 组件就是一种特殊的指令:NG中组件继承自指令,组件是一种特殊的指令
Component extends Direvtive
- 结构型指令,影响dom树结构的指令,必须以*号开头
ngFor 、ngIf 、ngSwitchCase、ngSwitchDefault
- 属性型指令,会影响dom元素的属性值 (类似:bind),必须使用[ ]括起来
[ngClass] [ngStyle] [ngSwitch] [(ngModel)]
- *ngFor:对数组或者对象进行遍历。使用这个指令,自动生成一个 index 也就是下标值
// html
<button (click)="addScore()">给数据添加随机数</button>
<h3>遍历数组</h3>
<ul>
<li *ngFor="let score of scores;let i=index">
{{score}}--{{i}}
</li>
</ul>
// component.ts
scores = [89, 91, 71];
addScore() {
const num = Math.floor(Math.random() * 100);
this.scores.push(num);
}
=======================================================================
// html
<h3>删除数据</h3>
<table>
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>操作</th>
</tr>
<tr *ngFor="let e of elist">
<td> {{e.eid}} </td>
<td> {{e.ename}} </td>
<td> {{e.gender==1?'男':'女'}} </td>
<td>
<button (click)="delete(i)">删除</button>
</td>
</tr>
</thead>
</table>
// component.ts
elist = [
{ eid: 101, ename: 'dingding', gender: 1 },
{ eid: 102, ename: 'tuangtuang', gender: 0 },
{ eid: 103, ename: 'biangbiang', gender: 1 },
];
delete(index) {
this.elist.splice(index, 1);
}
- *ngIf:true 则挂载指定元素,false 删除指定元素
// html
<button (click)="isShow=!isShow">显示与隐藏</button>
<ng-container *ngIf="isShow; else noShow">
显示
</ng-container>
<ng-template #noShow>
隐藏
</ng-template>
// component.ts
isShow=true;
- ngSwitch:实现多条件判定
传统switch
var status=10;switch(status){
case 10: ...
break;
case 20: ...
break;
default:
...}
ngSwitch——属性指令 [ngSwitch]=10
ngSwitchCase——结构指令 *ngSwitchCase=10
ngSwitchDefault——结构指令 *ngSwitchDefault
面试会问 ngSwitch 是什么指令?
<div [ngSwitch]="status">
<p *ngSwitchCase="1">
等待...
</p>
<p *ngSwitchCase="2">
完结...
</p>
<p *ngSwitchDefault>
走起...
</p>
</div>
status=1;
- ngStyle 和 ngClass
import { Component } from "@angular/core";
@Component({
selector:'style-class-demo',
// 使用css属性选择器要要引入css文件
styleUrls:['../assets/css/bgcolor.css'],
template:`
<h3>ngStyle和ngClass的演示</h3>
<p [ngStyle]='{"background-color":"#006699"}'>第一段话</p>
<p [ngStyle]='styleObj'>第二段话</p>
<div [ngClass]='classObj'>class</div>`
})
export class StyleClassDemo{
styleObj={
'background-color':'#990066',
'color':'#fff'
};
classObj={'bgcolor':true};
}
注意:
使用 NgClass 需要在 @Component 中引用写好的 css 样式
styleUlrs: ['../assets/css/*.css']
其实,搞个全局 css 文件就行,其他笔记中会介绍 css 文件的引用方式。
- 自定义指令
import { Directive, ElementRef } from "@angular/core";
@Directive({
//定义使用指令时的名称
selector:'[xzFocus]'
})
export class xzFocus{
// 指令的真正作用---构造函数
// 如何获取当前的 dom 节点对象 el:ElementRef
// 只能获得当前元素对象,无法获得当前元素
constructor(el:ElementRef){
// el.nativeElement 才是真正的 dom 树上的对象
console.log(el.nativeElement);
// 哪一个元素获取焦点
el.nativeElement.focus()
}
总结:
-
装饰器是 @Directive
-
装饰器中的 selector:'[xzFocus]'
-
注册与 component 一样
-
使用 <input xzFocus>
-
在对象的构造函数中,写真正的指令作用代码
-
如果获取当前使用指令的 dom 对象
通过参数 el:ElementRef(ElementRef 需要引用)
el.nativeElement ---> 才是使用指令的 dom 对象
- 双向绑定 [(ngModel)]
使用ngModel的步骤
1.导入包@angular/Forms中的{ FormsModule }
2.在模块中的imports属性中注册这个对象,才能使用
3.使用双向绑定 [(ngModel)]='kw'
import { Component } from "@angular/core";
@Component({
selector:'ngmodel-demo',
template:`
<h3>双向绑定的演示</h3>
<input type="text" [(ngModel)]='kw'>
<p>{{ kw }}</p>`
})
export class NGModelDemo{
// 双向绑定找不到数据了
// view中kw
innerkw='Dell';
get kw(){
console.log('get kw');
return this.innerkw;
}
// 只要有人想改变 kw,set 会自动调用
set kw(val){
console.log('set kw');
this.innerkw = val;
//此处可以根据用户的输入执行 XHR 的异步请求
}
}
练习:模拟百度搜索自动联想
VueJS 中
new Vue({
data(){
return { kw=''}
},
watch{
kw:function()}
}
});
Angular 中,使用set/get方法,对数据进行监听
import { Component } from "@angular/core";
@Component({
selector:'ngmodel-demo',
template:`
<h3>双向绑定的演示</h3>
<input type="text" [(ngModel)]='kw'>
<p>{{kw}}</p>
`
})//55下课 ,10点07上课
export class NGModelDemo{
//双向绑定找不到数据了
//view中kw
innerkw='Dell';
get kw(){
console.log('get kw');
return this.innerkw;
}
//只要有人想改变KW,set会自动调用
set kw(val){
console.log('set kw');
this.innerkw=val;
//此处可以根据用户的输入执行XHR的异步请求
}
}
网友评论