Angular-03:组件模板
各种学习后的知识点整理归纳,非原创!
组件模板
- ① 数据绑定
- ② 属性绑定
- ③ 类名绑定
- ④ 样式绑定
- ⑤ 事件绑定
- ⑥ 获取原生DOM对象
- 6.1 在组件模板中获取
- 6.2 在组件类中获取
- ⑦ 双向数据绑定
- ⑧ 内容投影
- 8.1 select选择器
- 8.2 单槽投影
- 8.3 多槽投影
- ⑨ 安全操作符(数据绑定的容错处理)
① 数据绑定
- 将组件类中的数据显示在组件模板中,组件类数据发生变化时会自动同步到组件模板中。(数据驱动DOM)
- 语法:{{}},插值表达式。
② 属性绑定
- DOM对象属性
- 语法:[属性名] // 属性名加中括号[]
<img [src]="imgUrl" />
- HTML标签属性
- [attr.属性名] // attr.属性名加中括号[]
- 自定义属性适用于该情况
<td [attr.colspan]="colspan"></td>
③ 类名绑定
- 语法1:[class.类名]=布尔值
- 语法2:[ngClass]={ 类名:条件 }
<p [class.active]="true"></p>
<p [ngClass]="{'a-name':true,'b-name':false}"></p>
④ 样式绑定
- 语法1:[style.css属性名]=条件;
- 语法2:[ngStyle]={css属性名:css属性值}
<p [style.width]="isDefault ? '100px' : '200px'"></p>
<p [ngStyle]="{'width':100px,'height':'200px'}"></p>
⑤ 事件绑定
<!-- 鼠标单击 -->
<p (click)="show($event)"></p>
<p (click)="show()"></p>
<!-- 按下enter键触发 -->
<input type="text" (keyup.enter)="show($event)" />
// ts中定义函数show
show(event:Event){
//...
}
⑥ 获取原生DOM对象
6.1 在组件模板中获取
举例:获取文本框中输入的值。
- #userName : 模板变量,变量中存储的就是原生Dom对象本身;
- 通过事件处理的方式传递到组件类中;
<!-- 输入完回车之后,可以通过定义的 `#username` 获取输入的值 -->
<input type="text" (keyup.enter)="getValue(username.value)" #username />、
// 在ts中定义模板变量和接收方法
// 该变量此处不定义也可以获取到,能正常运行。但是在ng build时可能会编译失败,有严格模式。
@ViewChild('username') username: ElementRef<HTMLParagraphElement | undefined>;
getValue(value: Event) {
console.log("value", value)
}
6.2 在组件类中获取
- @ViewChild属性装饰器,用来从模板视图中获取匹配的元素。
- 视图查询在ngAfterViewInit钩子函数调用前完成,所以在该函数中才能获取到查询元素。
稍微有点详细的用法:angular知识点–@ViewChild详解
举例1: 使用ViewChild装饰器获取一个元素
- 在组件模板上添加模板变量。
- 在组件类中使用@viewChild装饰器获取模板变量。
- @ViewChild是装饰器函数,参数是定义的模板变量名(pName),然后赋值给新的变量pElement(也可以理解为取了个别名)。 声明该变量的类型,undefined可以理解为类型保护,不会因为未获取到该元素而报错。
<p #pName> hello! </p>
// 在ts中定义该模板变量
@ViewChild("pName") pElement:ElementRef<HTMLParagraphElement> | undefined;
ngAfterViewInit(){
console.log("pName", this.pName && this.pName.nativeElement);
}
输出截图:(截图放错了,应该输出的时hello!)
举例2: 使用ViewChildren装饰器获取一组元素
- 使用@ViewChildren() 装饰器从组件模板中获取匹配多个元素,返回的结果是一个QueryList集合。
<ul>
<li #items>a</li>
<li #items>b</li>
<li #items>c</li>
<li #items>d</li>
</ul>
@ViewChildren("items") liElements:QueryList<HTMLElement> | undefined;
ngAfterViewInit(){
console.log("items",this.liElements)
console.log("items",this.liElements.toArray())
}
打印1:
打印2:
⑦ 双向数据绑定
- 数据在组件模板和组件类中双向同步。(在组件模板中数据做了更改会在组件类中同步跟随变化,反之一样)
- 常用于表单中,所以该模块依赖于angular表单模块,需要导入FormsModule。
- 语法:[(ngModule)]=“变量名”
举例:在input文本框内输入值的时候,userName值一直在改变。在组件类的方法中也在影响着组件模板中的值。
<input type="text" [(ngModule)]="userName" />
<button (click)="changeValue()">在组件类中更改</button>
// ts
userName:string="";
changeValue(){
this.userName="hello angular";
}
⑧ 内容投影
- ng-content,也叫内容嵌入,是组件的一个高级功能特性。
- 能够很好的扩充组件功能,方便代码的复用。常用于用来创建可复用的组件。
- 可以理解为:在编写模板组件时,使用ng-content做一个占位符,引用组件时,往此处填充。
- 在定义多个插槽时,插槽的顺序就是内容最终的显示顺序。(在使用插槽时的内容顺序不会生效)
- 另外一篇指路:angular知识点–组件内容嵌入
8.1 select选择器
可理解为css选择器,作用是类似的。
类型 | 用法 |
---|---|
html标签 | select=“标签” |
css类名 | select=“.类名” |
自定义组件名称 | select=“组件名” |
自定义属性名称 | select=“[属性名]” |
举例:场景:制作一个可复用的导航栏(NavComponent),导航栏的内容可动态变化
8.2 单槽投影
一个ng-content,不使用select选择器
<!-- NavComponent -->
<!-- 一个导航栏,左边是返回按钮,中间ng-content是可动态替换的内容。 -->
<div class="nav-wrapper">
<span>返回</span>
<div class="content">
<ng-content></ng-content>
</div>
</div>
<!-- 在其他组件使用NavComponent 组件-->
<!-- app-nav 中的 p标签的内容会被填充显示到ng-content区域-->
<app-nav>
<p>测试文字</p>
</app-nav>
结果:
8.3 多槽投影
- 多个ng-content,使用select选择器
- 一个组件多个插槽,需要使用select与让插槽与元素有一一对应关系。
- 在引入的app-nav中添加多个条件的内容,让app-nav组件的的select选择器去匹配
- 在使用插槽的时候,不根据在引用组件中定义的内容顺序显示,而是根据在定义插槽时排列的顺序。
- 这里使用插槽时,顺序与app-nav组件模板中定义的插槽不一致,生效的时插槽内的顺序。
<app-nav>
<p>测试文字(默认)</p> <!-- 无法匹配到,因为没有符合条件的选择器,页面上也不会渲染该节点 -->
<span>匹配标签选择器</span>
<P class="head">匹配类选择器</P>
<p userName="'nothing'">匹配属性选择器</p>
<app-test></app-test> <!-- 匹配app-test选择器。显示组件内的默认内容:app-test works! -->
</app-nav>
在app-nav组件内添加多个ng-content与之匹配的选择器。
<!-- app-nav组件 -->
<div class="nav-wrapper">
<span>返回</span>
<div class="content">
<!-- 标签 -->
<ng-content select="span"></ng-content>、
<!-- css类名 -->
<ng-content select=".head"></ng-content>、
<!-- 组件名 -->
<ng-content select="app-test"></ng-content>、
<!-- 自定义属性 -->
<ng-content select="[userName]"></ng-content>
</div>
</div>
结果:
- 除了第一条不符合选择器匹配规则,其他的分别都匹配上了
⑨ 安全操作符(数据绑定的容错处理)
- 当属性不存在或者属性为可选的或者对象层级较深,angular会有报错
几种处理手段:
<p>{{user?.name}}</p> //user存在才会取name值
<p *ngIf="user">{{user.name}}</p>
<p> {{user && user.name}}</p>