一、 简介
Angular是一个功能非常完备的前端框架,最早由 Misko Hevery 等人创建,2009 年被Google 公式收购,用于其多款产品。Angular基于TypeScript,通过增强HTML的方式提供一种便捷开发Web应用程序的方式。
这里主要介绍在angular开发使用后的一些经验总结,还有踩过的坑。
绑定是一项很好用的功能,也是angular的特点之一。
(1) 事件绑定
<button (click)="doClick($event)">按钮button>
(2) 属性绑定
<img [src]="imgUrl"/>
<img src="{{imgUrl}}"/>
<td [attr.colspan]="size">td>
<span [attr.name]="name">span>
(3) Class绑定
<div [class]="divClass">div>
<div [ngClass]="{number>3?divClass1:divClass2}">div>
<div [ngClass]="{divClass:number>3}">div>
(4) 样式绑定
<div [style]="divStyle">div>
<div [style.color]="{number>3?red:green}">div>
<div [ngStyle]="{divStyle:number>3}">div>
(5) 双向绑定
<input [(ngModel)]="form.name"/>
<label">{{name}}label>
Angular的form表单提供了简单方便的验证方法,及样式控制,这里举个简单的例子。关键部分是#addForm和#name
<div>
<formclass="form-inline" #addForm="ngForm">
<divclass="form-group">
<labelfor="name"class="control-label"><spanstyle="color:red;">*span>名称:label>
<inputclass="form-control" [(ngModel)]="form.name"required #name="ngModel"/>
<div [hidden]="name.valid|| name.pristine"class="alertalert-danger">名称不能为空div>
div>
form>
<buttontype="submit"class="btnbtn-ok" (click)="saveName()" [disabled]="!addForm.form.valid">保存button>
div>
管道是一个很好用的功能,可以多页面公用处理方法,使用简单。可以使用angular内置管道,也可以自定义管道
<span>{{time |date: 'y-MM-dd HH:mm:ss'}}span>
<span>{{status |statusPipe}}span>
自定义管道方法
import {Pipe, PipeTransform } from'@angular/core';
@Pipe({
name:'statusPipe'
})
exportclassStatusPipePipeimplementsPipeTransform {
transform(value:any, args?: any):any {
lettransVal ='';
switch (value) {
case'activated':
transVal ='已激活';
break;
case'unactivated':
transVal ='未激活';
break;
}
returntransVal;
}
}
路由有很多配置参数,这里只举例路由传参 /login/1?name=1
页面中路由跳转
[aueryParams]="{name:1}"target="_blank">login
Ts中路由跳转
this.router.navigate(['login',1],{ queryParams: { name: 1 } });
Web项目中发送请求是比不可少的,一般使用统一的http请求服务,对请求进行统一的拦截处理是一个常用操作。
post (url:string, params?: any) {
url = this.getUrl(url);
returnthis.http.post(url,params)
.toPromise()
.then(this.intercept) // 使用拦截器
.catch(this.handleError);
}
// 拦截器
privateintercept(res :any){
if (res["_body"].indexOf("noright") > 0) {
alert("没有权限访问");
}else{
returnres.json();
}
}
组件是Angular的一个特色,组件的使用方便了代码复用。Angular提供了组件直接通信的方法。
父组件属性count传给子组件,子组件方法save返回父组件。
<divclass="parent">
<app-child #childComponent [count]="count" (save)="onSave($event)">app-child>
div>
子组件使用@Input、@Output来进行通信。通过@Input获取父组件count值,通过@Output将数据传递给父组件。
exportclassChildComponentimplementsOnInit {
@Input()privatecount:number;
@Output()save: EventEmitter<any> =newEventEmitter();
privatename:string;
saveCall(event:any) {
this.count++;
that.save.emit(this.count);
}
edit() {
this.count=5;
}
}
父组件在onSave方法接收子组件传递过来的值,另外父组件也可以使用ViewChild调用子组件属性和方法。
exportclassParentComponentimplementsOnInit {
@ViewChild('childComponent')childComponent:ChildComponent;
ngOnInit() {
this.childComponent.name='Lily';
this.childComponent.edit();
}
// 保存回调
onSave(data:any) {
console.log(data);
}
}
在javascriptfunction中调用typescript中方法,导致this指向并不是我们原始的this问题,原因是 js的代码作用域影响,可以通过下面方法解决。
letthat =this; //重要
// 使用that指向typescript中方法
在angular中路由到某个页面,例如/data,在当前页面刷新,我们期望的是当前页面,实际却跳转到了首页/home。通过设置useHash参数解决,但是url中会增加#号,例如#/home,#/data
RouterModule.forRoot(appRoutes, {useHash:true})
在Web前端开发中,我们经常会遇见需要动态的将一些来自后端或者是动态拼接的HTML字符串绑定到页面DOM显示,angular提供了内置指令[innderHtml]="htmlContent"实现,但是htmlContent中带有的style样式会被过滤。原因是angular自身有一套安全过滤系统,我们必须为html标签添加信任,才能正常显示。解决方法是使用angular服务DomSanitizer中的bypassSecurityTrustHtml 方法
前端:
后端
到这里已经解决问题了。为了不影响源数据和批量使用,可以封装成管道,这样各页面和数据都不用修改,只在前端使用管道即可。
第三方库引入angular后,有时候会出现加载不出来或者函数不识别、显示不正确等问题,可能有以下三方面的原因:没有声明,页面元素display为none,dom不存在。
第三方库引入后需要声明,例如
declarevarecharts:any;
有些js加载时要求页面元素display不能为none,如果需要控制显示隐藏,可以使用ngIf,不要通过display实现。
<divstyle="display:none">div>
<div *ngIf="flag==1">div>
有时候第三方js在页面中不能正常显示,主要是angular的动态加载引起的,因为js加载时页面元素不存在。如果需要在弹窗或者动态生成的元素中加载,可以通过onShown回调或者setTimeout延迟加载,等dom存在之后初始化js就可以正常显示了。
Angular功能很强大,而且使用非常灵活,也很方便集成。缺点是性能,库比较大,页面响应慢。还有一点就是,angular版本变化快,学习曲线陡峭,在开发效率方面需要注意。