本帖最后由 AreYouGlad 于 2018-1-8 19:59 编辑
查看更多精彩前端资源
模版引擎
Angular集成了强大的模板引擎用于视图的开发, 这套引擎让我们在大部分情况下不用手动操作DOM 接下来我们就基于脚手架工具生成的项目进行学习, 修改的代码主要是项目的src/app目录
插值表达式 使用尝试[JavaScript] 纯文本查看 复制代码 export class AppComponent {
title = 'app';
site = '深圳'; // 自己添加的属性
constructor() {}
}
- 然后打开app.component.html, 把{{ title }}插值表达式中的title换成site进行保存
[JavaScript] 纯文本查看 复制代码 <h1>
Welcome to {{ site }}!
</h1>
然后查看浏览器, 原本的app变成了深圳, 整个过程我们没有涉及到任何DOM操作 回想一下你之前使用过的模版引擎, 是不是觉得Angular的模版引擎很酷
基本运算[JavaScript] 纯文本查看 复制代码 <h1>
Welcome to {{ site }}!
</h1>
<p>{{ site == '深圳'? '房子太贵我要离开': '哥甚是怀念深圳蜗居的日子' }}</p>
事件绑定 尝试点击事件[JavaScript] 纯文本查看 复制代码 <!-- 事件绑定语法: (事件名)=函数() -->
<button (click)='clickHandler()'>点我</button>
- 在app.component.ts文件中添加对应的clickHandler方法
[JavaScript] 纯文本查看 复制代码 export class AppComponent {
title = 'app';
site = '深圳';
// 点击事件处理函数
clickHandler(): void {
console.log('按钮被点击');
}
}
尝试表单事件有些时候在事件触发时我们需要拿到对应的事件对象 那么可以在模版中把$event变量传给函数, 下面使用input事件演示 注意: 因为随着代码累加越来越多, 所以下面的代码都是新添加的代码片段
[JavaScript] 纯文本查看 复制代码 <!-- 如果需要事件对象, 那么传入$event即可 -->
<input type="text" (input)='inputHandler($event)'>
// 表单事件处理函数
inputHandler(e): void {
console.log(`表单最新值为: ${e.target.value}`);
}
数据绑定特性学习了插值表达式与事件处理之后, 我们可以见识一下Angular的数据绑定特性了 修改刚刚的inputHandler函数为下面的样子, 然后试着在浏览器表单中输入值 你会发现属性发生变化时, angular会自动更新视图, DOM操作你又省了
[JavaScript] 纯文本查看 复制代码 // 表单事件处理函数
inputHandler(e): void {
this.site = e.target.value; // 修改site属性的值
}
指令
前面都只是模版最基本的组成部分, 更强大的功能莫过于指令了 在Angular中指令就是具有特殊功能的属性, 这些特殊的属性扩展了html的功能 其实上面的事件绑定语法就是指令的一种, 它使用了(事件名)这样的特殊属性
*ngIf[JavaScript] 纯文本查看 复制代码 <!-- isTure的值控制元素的添加移除 -->
<p *ngIf="isTure">控制我的添加与移除</p>
export class AppComponent {
title = 'app';
site = '深圳';
isTure = false; // 使用这个值控制元素
}
数据驱动开发思想[JavaScript] 纯文本查看 复制代码 <!-- *ngIf, isTure的值控制元素的添加移除 -->
<div>
<p *ngIf="isTure">控制我的添加与移除</p>
<button (click)='clickAddOrRemove()'>{{ isTure? '移除': '添加' }}</button>
</div>
export class AppComponent {
title = 'app';
site = '深圳';
isTure = false; // 使用这个值控制元素
// 点击事件, 只要修改isTure属性, 就可以控制元素的添加移除
clickAddOrRemove(): void {
this.isTure = !this.isTure;
}
}
*ngFor基本使用[JavaScript] 纯文本查看 复制代码 <!-- *ngFor, 里面采用的语法是固定格式 -->
<ul>
<li *ngFor="let city of cityList">{{ city }}</li>
</ul>
export class AppComponent {
title = 'app';
site = '深圳';
isTure = false; // 使用这个值控制元素
cityList = [
'北京',
'上海',
'广州',
'深圳'
];
} 拿到数组下标[JavaScript] 纯文本查看 复制代码 <!-- *ngFor, 下面是获取下标并使用的语法 -->
<ul>
<li *ngFor="let city of cityList; let i = index">{{ i }} : {{ city }}</li>
</ul> 性能优化
Angular内部会使用这个值作为元素的ID, 当数据变化时, 新旧ID会进行比较以判断是否有必要重新渲染这个元素
大多数情况下我们无需设置它, 如果我们渲染的数据比较复杂可能需要考虑一下
PS: 这里通过修改部分数据, 来给大家演示当数据变化时, angular会有选择性的重新渲染部分元素
[JavaScript] 纯文本查看 复制代码 <ul>
<!-- *ngFor, 下面是添加trackBy的语法, trackBy要求赋值一个函数, 这里把trackByCity赋了过去 -->
<li *ngFor="let city of cityList; let i = index; trackBy: trackByCity">{{ i }} : {{ city }}</li>
</ul>
export class AppComponent {
cityList = [
'北京',
'上海',
'广州',
'深圳'
];
// trackBy函数会自动接收到ngFor遍历到的下标与item
// 这里因为数据结构比较简单, 把下标与值拼在一起作为元素ID返回
trackByCity(index: number, item: any) {
return index + '_' + item;
}
} trackBy简写
如果你的数据本身就具有ID这样的唯一属性, 那么你可以省略函数的编写
因为trackBy的值也可以是一个基本数据类型, 查看下面的代码
[JavaScript] 纯文本查看 复制代码 <ul>
<!-- 这里需要注意的是里面赋值时使用的?号, 没有它将报错 -->
<li *ngFor="let user of userList; trackBy: user?.id">{{ user.name }}</li>
</ul>
export class AppComponent {
userList = [
{name: '花花', age: 16, id: 10001},
{name: '草草', age: 18, id: 10002}
{name: '云云', age: 20, id: 10003},
{name: '朵朵', age: 15, id: 10004}
];
} ngSwitch指令组
有些时候我们需要根据一个变量的值来展示不同的内容 使用*ngIf可以解决我们的问题, 但是他们看起来并不是一组, 使用ngSwitch指令组会更好 ngSwitch指令组由三个不同指令构成:[ngSwitch] *ngSwitchCase *ngSwitchDefault
其中[]包起来的指令叫属性指令, 这种指令会修改DOM对象的属性
然后*号开头的指令叫结构指令, 这种指令会进行DOM的添加移除
[HTML] 纯文本查看 复制代码 <!-- ngSwitch指令组,这里使用以前的site数据进行控制 -->
<!-- 其中的*ngSwitchCase因为不使用数据绑定,而是写死的字符串,所以里面的值添加单引号包裹 -->
<div [ngSwitch]='site'>
<p *ngSwitchCase="'北京'">北京冬天有暖气</p>
<p *ngSwitchCase="'上海'">上海冬天有空调</p>
<p *ngSwitchCase="'深圳'">深圳冬天要裹被</p>
<p *ngSwitchDefault>不管在哪, 只要不过冬天就好</p>
</div> 属性指令 - 原生的DOM属性修改
属性指令的语法是使用[]包起来, 里面可以书写angular扩展的DOM属性, 也可以写原生DOM属性
下面给出的范例都是操作原生的DOM属性
innerHTML属性[JavaScript] 纯文本查看 复制代码 <!-- 使用[]属性指令语法动态修改元素的innerHTML -->
<div [innerHTML]="tpl"></div>
export class AppComponent {
title = 'app';
tpl = `<div>
<h4>我是数据里的字符串模版</h4>
<h4>我是数据里的字符串模版</h4>
</div>`;
} 其他属性范例[JavaScript] 纯文本查看 复制代码 <div>
<a [href]="aHref">点击跳转</a>
<img [src]="imgSrc"/>
</div>
export class AppComponent {
aHref = 'http://www.baidu.com';
imgSrc = 'http://www.baidu.com/img/bd_logo1.png';
} container容器
Angular不允许在一个元素上使用多个结构性指令(*打头的都为结构性指令)
那么可以通过嵌套一个<ng-container>标签, 给它添加控制指令来解决
这个元素在渲染时不会在页面上留下任何痕迹, 作用只是单纯的增加一些逻辑处理
错误范例[HTML] 纯文本查看 复制代码 <ul>
<li *ngFor="let city of cityList; let i = index" *ngIf="i % 2 == 0">{{ i }} : {{ city }}</li>
</ul> 解决方案[HTML] 纯文本查看 复制代码 <!-- 不能在一个元素上使用多个结构性指令,那么可以嵌套ng-container标签解决 -->
<ul>
<ng-container *ngFor="let city of cityList; let i = index">
<li *ngIf="i % 2 == 0">{{ i }} : {{ city }}</li>
</ng-container>
</ul> [(ngModel)] - 双向数据绑定
这是一个用于表单的双向数据绑定指令, 前面我们使用的插件表达式或指令都是单向的数据绑定
单向的特点是数据发生变化, 视图跟着变化
但是对于表单元素来说, 我们希望的是表单变了数据变, 数据变了表单变
准备工作
使用这个指令我们需要从'@angular/forms'中导入FormsModule模块然后配置到根模块依赖中
首先打开根模块app/app.modules.ts文件, 然后编写下面的代码
[JavaScript] 纯文本查看 复制代码 import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// 导入表单模块
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule // 把表单模块配置进来
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { } 使用[JavaScript] 纯文本查看 复制代码 <div>
<h2>请输入新密码</h2>
<!-- 使用了双向数据绑定后, password的值会自动显示到表单, 表单改变时password也自动改变 -->
<input type="text" [(ngModel)]="password">
<span>{{ password }}</span>
</div>
export class AppComponent {
password = '默认密码';
}
|
|