Angular4.0基础知识之组件
Angular4.0基础知识之路由
Angular4.0依赖注入
Angular4.0数据绑定&管道html
数据绑定容许你将组件控制器的属性和方法与组件的模板链接起来,大大下降了开发时的编码量。前端
常见的表现形式有:typescript
<h1>{{title}}</h1>
,即把属性|表达式插入到HTML标签中<img [src]="imgUrl" />
,也就是将属性|表达式绑定到HTML标签的属性上<button (click)="show()"></button>
,讲组件控制器的一个方法绑定到模板元素的事件上在Angular中,默认的数据绑定是单向的(AngularJS1.0中所有是双向绑定,这也是性能差的缘由之一),所谓的双向绑定,也就是控制器的属性反映到模板中,同时,模板中显示出的属性被修改以后,对应的控制器属性同时发生变化;单向绑定取出了模板=>控制器的方向,使性能大大提高。(固然,双向绑定并非被去掉了,你也能够手动指定使用双向绑定,双向绑定如今变成了一个可选项,而不是框架的默认行为)数组
<button (click)="doOnClick($event)"></button>
doOnClick(event:any){ console.log(event); }
如上代码是一个经典的事件绑定例子,被绑定的事件能够是一个标准事件也能够是一个自定义事件,绑定的操做能够是控制器里的一个方法,也能够只一个赋值表达式等等。服务器
以下例子所示app
// 使用属性绑定 <img [src]="imgUrl" /> // 使用插值表达式 <img src="{{imgUrl}}" />
又是一个经典的例子,不难理解,上面两个方法实现的效果是彻底一致的,事实上,这两个方法没有优劣之分,你只须要按照本身的喜爱去选择便可框架
<td [attr.colspan]="value"></td>
<div class="aaa bbb" [class]="val"></div> // 这种状况会覆盖原先的class <div [class.aaa]="booleanVal"></div> // 经过一个Boolean值开关来控制是否启用某一个class名,适合管理单一class名 <div [ngClass]="{aaa:isA,bbb:isB}"></div> // 经过对象的形式开控制多个class的开关,适合同时管理多个className
和class绑定相似,只不过绑定的对象为style属性工具
<button [style.color]="isRed?'red':'green'">Red</button> <div [ngStyle]="{color:red,'font-style':bool?'italic':'normal'}"></div>
双向绑定即视图和模型保持同步,不管视图和模型哪一方改变,另外一方都一块儿同步改变。性能
前面所学到的事件绑定是从视图到模型,把模板中元素的事件绑定到控制器中的方法;属性绑定的方向是从控制器到模板,使用方括号讲组件控制器的属性绑定到模板。this
<input [value]="name" (input)="doOnInput($event)" />
export class BindComponent implements OnInit { name: string; doOnInput(event){ this.name=event.target.value; } }
这样就实现了一个双向绑定,当input内容变化的时候,出发事件,修改模型中的属性值,当模型中的属性值改变的时候,优惠在视图中表现出来。
固然,Angular确定提供了内置的双向绑定支持:
<input [(ngModel)]="name" />
因为[(ngModel)]
用在input元素上,默认绑定的是input
事件。双向绑定最经常使用的用途就是表单处理。
固然,双向绑定原本就应该用于input系列元素上,由于这些元素容许你去修改这些值,并显示出来。
将会在表单处理章节更详细讲。
举个例子,例如我要在页面上显示个人生日信息,假设如今从服务器获取到的日期是一个Date对象,那么把它直接输出到页面上确定是用户体验很很差的(一大串乱七八糟的字符串)。管道就是用来处理数据的,从原始值到你所须要的值,这一个过程。
使用实例:
<p>{{birthday | date | uppercase}}</p>
上面例子中咱们就使用了两个内置的管道,第一个是获取到Date对象的日期信息,第二个是把小写字母转换成大写。
经常使用的管道:
date日期管道
日期管道符能够接受参数,用来规定输出日期的格式。
<p>如今的时间是{{today | date:'yyyy-MM-dd HH:mm:ss'}}</p>
number 数字处理管道
接收的参数格式为{最少整数位数}.{最少小数位数}-{最多小数位数}
其中最少整数位数默认为1
最少小数位数默认为0
最多小数位数默认为3
当小数位数少于规定的{最少小数位数}时,会自动补0
当小数位数多于规定的{最多小数位数}时,会四舍五入
ng g pipe pipe/multiple
,此处用来作Demo的管道做用是扒一个数放大n倍,也就是乘法……生成的管道代码:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'multiple' }) export class MultiplePipe implements PipeTransform { transform(value: any, args?: any): any { return null; } }
能够看出,管道是一个实现了PipeTransform而且带有@Pipe装饰器的类,用于把源数据根据参数和方法定义处理成想要的结果。
可是,当你打开
app.modules.ts
的时候,你会发如今declaration数组里多出来了一个MultiplePipe的声明,也就是说,管道也是须要声明的,只是命令行工具自动添加进去了。
其中value是管道前端的原始值,args是一个可选参数,也就是管道的参数,最终管道把处理结果返回出去便可。
以下,咱们很轻易地建立了一个管道:
import {Pipe, PipeTransform} from '@angular/core'; @Pipe({ name: 'multiple' }) export class MultiplePipe implements PipeTransform { transform(value: number, args?: number): number { if (!args) { args = 1; } return value * args; } }
在实战项目中,咱们对管道有了新的用法,根据传入的参数来过滤商品列表:
import {Pipe, PipeTransform} from '@angular/core'; import {Product} from '../shared/product.service'; @Pipe({ name: 'productFilter' }) export class ProductFilterPipe implements PipeTransform { transform(productList: Product[], filterField: string, keyword: string): any { if (!filterField || !keyword) { return productList; } return productList.filter((product: Product) => product[filterField].indexOf(keyword) >= 0); } }