最近这段时间发现,北京这用angular4 或 angular2的公司不多。几乎是没有。很担忧本身是否是把精力放到了不该该的地方。白耽误了时间。可是随着我对新版angular框架理解的加深。我的感受angular4未来会有很大的前景,通用化,组件化,注入服务。用于开发复杂的JS前端应用真是太方便了。而且听说angular5会更优秀。或许目前的状况是对新版angular框架研究早了几年时间吧。前端
这几天作了修改密码,用到了自定义指令,验证新密码和确认新密码是否相同。这个是简单的。全是前端来判断。网上也有不少例子,百度“angular4 自定义指令“ 。会列出不少资料。修改一下就能运行成功。数据库
当两个密码一致后,在去修改新密码,会显示以下。服务器
想要简单一点就是写两个自定义验证指令。一个检验新密码,一个检验确认新密码。不必定向网上那些例子同样,必定要放到一个验证指令内。可是更多时候,咱们是要验证当前输入数值,是否在服务端对应数据库内有重复的存在。好比模块管理页面上restful
模块名称和模块URl都是不能重复的。底层会经过模块URl进行页面定位。因此在进行添加和修改的时候。须要远程数据校验,在服务器端进行数据检测,看看要添加或修改的数值在服务端是否重复存在。这个用angular4的自定义指令来实现。自定义指令都是继承validate接口。核心是 validate函数。 网络
validate(c: AbstractControl): { [key: string]: any }
可是validate函数是按键触发,每修改一下数据就执行一次,好比咱们在确认新密码检验治理的validate函数里加上一个输出,angular2
而后执行下修改密码操做。这里为了显示方便,我先把input的 type="password" 修改成 type="text" 框架
在确认新密码那我输入了9个数字,validate函数就执行了9次。这个机制用来检验两个密码是否一致是能够的。可是要检测远程数据表中的数据是否有重复。那是绝对不行,每一个字符的修改都要远程检测一次,服务端和网络的压力会过大。angular4
因此思路应该是用户在input内输入的时候咱们不检测。当input丢失焦点的时候开始检测。经过http链接远程的restful接口。在远程数据库内查询。按这个思路添加的时候没问题。可是修改的时候就有问题。好比input内已经有一个数值。input得到焦点,可是不修改任何数值,在让input丢失焦点。那这时候也会去后台数据库检测一次,可是在后台就会查出当前input内的数值有一个存在。ide
因此在数据库检测的时候要区分为添加检测和修改检测两种来进行。其实更好的思路是input一获取焦点,就保存当时value数值。在input丢失焦点的时候在获取一次value数值。远程请求前先判断下两个数值是否一致。不一致的时候链接restful接口进行校验。因此完整的调用方式以下。函数
checkvalue 是自定义检验指令,属性数值1 或2 是本身扩展的。这个数值传递到ssm框架的服务端。用来指明是对那个数据表的那个字段进行是否重复检验。这里多说下,其实更简单是把服务端数据表名称和字段名称直接写到checkvalue=" " 的属性数值里。可是这样会让服务端的数据表名称和字段名称暴露在前台。因此我这里写了一个数字,传递到后台,用来作索引。更好的索引是传递guid。但这里我就不写了,之后修改也是很容易。
import { Inject, Input, Directive, forwardRef, Attribute, HostListener } from '@angular/core'; import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms'; import { CheckValuePackage } from '../module/common/common'; import { UserNews } from '../module/business/login'; import ConstantsList from '../common/constants/config'; @Directive({ selector: '[checkvalue][formControlName],[checkvalue][formControl],[checkvalue][ngModel]', providers: [ { provide: NG_VALIDATORS, useExisting: CheckValueValidator, multi: true }, ] }) export class CheckValueValidator implements Validator { _v: string; _e: string; _default: string; _openType: number = 0;// 打开方式 0 没有打开,1 添加打开 , 2 修改打开 _c: AbstractControl constructor( @Attribute('checkvalue') public checkvalue: string, @Attribute('openstate') public openstate: number, @Inject('auxiliary') public auxiliary, @Inject('checkvaildator') public checkvaildator) { } @Input('openstate') set setOpenstate(opentype: number) { this._openType = opentype; }; validate(c: AbstractControl): { [key: string]: any } { this._v = c.value; this._e = this.checkvalue; this._c = c; return null; } @HostListener('blur') //丢失焦点触发 onblur() { let cv: CheckValuePackage = new CheckValuePackage(); cv.sendvalue = this._v; cv.runtype = this._e; cv.opentype = this._openType; let userNews: UserNews = this.auxiliary.getUserNews(); let sendtoken: string = userNews.id + '-' + userNews.token + '-' + ConstantsList.runid; if (cv.sendvalue !== this._default) { this.checkvaildator.CheckValue(cv, sendtoken).then( ub => { let backCode: number = ub.backCode; switch (backCode) { case -1: this._c.setErrors({ checkvalue: true, message: '远程验证发生错误' }); break; case 0: this._c.setErrors(null); break; default: this._c.setErrors({ checkvalue: true, message: '此数值后台已经存在,不可重复' }); break; } } ); } } @HostListener('focus') //获取焦点触发 onfocus() { this._default = this._v; } }
写入已经存在的数值,好比这里写入公共模块的名称和url。在imput丢失焦点的时候,进行后台检测。检测不经过不可提交
修改数据,打开模块管理。选择惟一没有被锁定的测试模块
弹出窗口以下
修更名称和URl为已经存在的其余模块的数值,这里咱们仍是把它修改成公用模块的名称和url
也会显示咱们指定的错误。这样咱们就实现了用自定义的angular指令。去后台进行远程数据检测的功能。并且咱们已经把它通用化,组件化了。
具体效果能够在 http://121.42.203.123 查看。这里例子上我只修改了模块管理页面的添加和编辑。其余的页面都没添加这个远程验证。