ng-alain表单使用方式详解


Posted in Javascript onJuly 10, 2018

Angular表单

Angular提供两种不同的架构范式表单:模板驱动和响应式表单,官网也简单实现了动态表单范例。

当使用两种不同范式构建一个用户必填性的表单,在使用上有非常大的不同:

模板驱动

@Component({
  template: `
  <form nz-form (ngSubmit)="onSubmit()">
    <nz-form-item>
      <nz-form-label nzRequired nzFor="name">Name</nz-form-label>
      <nz-form-control>
        <input [(ngModel)]="model.name" name="name" id="name" required #name="ngModel">
        <nz-form-explain [hidden]="name.valid || name.pristine">Name is required</nz-form-explain>
      </nz-form-control>
    </nz-form-item>
  </form>`
})
export class DemoComponent {
}

响应式

@Component({
  template: `
  <form nz-form [formGroup]="heroForm" (ngSubmit)="onSubmit()">
    <nz-form-item>
      <nz-form-label nzRequired nzFor="name">Name</nz-form-label>
      <nz-form-control>
        <input formControlName="name">
        <nz-form-explain [hidden]="name.valid || name.pristine">Name is required</nz-form-explain>
      </nz-form-control>
    </nz-form-item>
  </form>`
})
export class DemoComponent {
  ngOnInit(): void {
    this.heroForm = new FormGroup({
      name: new FormControl('', [Validators.required])
    });
  }
  
  get name() { return this.heroForm.get('name'); }
}

上述示例只提供核心代码

诚如模板驱动和响应式表单的名称一样。模板驱动以HTML编程风格为主,并且由 ngModel 创建表单控件对象及数据模型管理,相比较响应式表单使用更少的代码(虽然看起来是这样)。

假如对测试非常在意,那么毋庸置疑响应式表单更适合你,因为二者的另一个重要区别是响应式表单数据模型及有效性信息都是同步行为,你可以更容易的测试他它们。

ng-alain表单构建方式

当然这一切都跟 ng-alain 并没有任何决定性关联,ng-alain 只是从使用的角度进一步优化二者的使用方式来做改变。

示例中不管是以HTML、还是以编程风格为主,总是需要很多额外的代码来做布局。

方式一:简易HTML模板表单

因此,当你是以HTML模板为主的表单开发,则简易HTML模板表单组件:shf-item 可能会更适合你,若将上述的示例使用 shf-item 来改变将会这样:

@Component({
  template: `
  <form nz-form (ngSubmit)="onSubmit()" shf-wrap>
    <shf-item label="App Key">
      <input [(ngModel)]="model.name" name="name" required #name="ngModel">
      <nz-form-explain [hidden]="name.valid || name.pristine">Name is required</nz-form-explain>
    </shf-item>
  </form>`
})
export class DemoComponent {
}

以之相对于的响应式表单略同,组件单纯只是进一步优化使用方式。

关于错误反馈

错误反馈包含视觉与信息文本两种,上述示例以信息文本为主(嗯,提示必填性真傻)。

视觉效果在ng-zorro-antd里,是将目标元素以红色边框线来表示(因此对于那些没有边框或没有特殊处理的都无法体现)。

建议:除特殊错误文本以外,可以只考虑以视觉效果来反馈错误。

关于校验

Angular 实现了部分HTML5标准常规属性,例如:required、maxlength 等等;而 ng-zorro-antd 的所有数据录入组件都包含了一些额外的数据限定条件,例如:nz-input-number 有效范围(nzMin、nzMax、nzStep)。当然可以进一步归纳业务校验逻辑,例如异步校验手机号码 mobile (可参考RequiredValidator)。

小结

shf-item 是以简化HTML布局开发的组件,自身会维护 ngModel 的状态变化并对目标元素增加 .has-error 样式类名,它始终保持视觉效果的体现。

方式二:动态表单

动态表单 @delon/form 是一个基于 JSON Schema 标准的动态构建表单;它是一个独立的类库,你可以在任何 ng-zorro-antd 项目中使用。

同样以相同的示例,其代码会有趣得多:

@Component({
  template: `<sf [schema]="schema" (formSubmit)="submit($event)"></sf>`
})
export class DemoComponent {
  schema: SFSchema = {
    properties: {
      name: { type: 'string' }
    },
    required: [ 'name' ]
  }
}

动态表单始终以一个JSON对象来构建表单,哪怕该对象来自远程。

@delon/form 内置仅实现 ng-zorro-antd 数据录入组件部分,你依然可以通过自定义小部件 方法实现一套属于自己业务部件库。

数据结构与UI

一个完整的表单元素我们认为应该包含以下若干元素:

ng-alain表单使用方式详解

JSON Schema 重点在于数据结构校验,而对于UI层面可以通过 <sf [ui]="ui"> 来额外增强 UI 渲染,例如:

schema = {
 properties: {
  url: {
   type: 'string',
   title: 'Web Site'
  }
 }
}

一个URL属性,若我们不希望用于添加 https:// 前缀的情况下,就单纯的 JSON Schema 结构是无法表述,而 nz-input 又支持非常丰富的前后缀文本,则我们可以为 ui 定制并增加 https:// 的前缀文本:

ui = {
 $url: {
  addOnBefore: 'https://'
 }
}

ui 本身也是一个 JSON 结构,为了区分 JSON Schema 属性名的对应关系,必须统一对属性名加上 $ 前缀。

小结

动态表单并不是基于 @angular/form 来构建的,但本质是略同,通过 Observable 监听数据流后使用ajv 校验、错误反馈。

总结

总的来说在 ng-alain 里可以采用 Angular 表单和动态表单两种方式,而 Angular 表单又有两种不同的架构范式表单:模板驱动和响应式表单。

前者若单纯使用 ng-zorro-antd 相对于缺少更加简洁的开发方法,shf 只是一个简洁的表现形式。

后者是一种比较可爱又相对通用的方式,因为JSON Schema规范是统一的,不管哪种前端框架都是相通。

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Prototype使用指南之selector.js说明
Oct 26 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
浅析jQuery(function(){})与(function(){})(jQuery)之间的区别
Jan 09 Javascript
设置jQueryUI DatePicker默认语言为中文
Jun 04 Javascript
jquery实现网站列表切换效果的2种方法
Aug 12 Javascript
js实现瀑布流效果(自动生成新的内容)
Mar 16 Javascript
JavaScript函数表达式详解及实例
May 05 Javascript
深入理解ES6学习笔记之块级作用域绑定
Aug 19 Javascript
使用JQ完成表格隔行换色的简单实例
Aug 25 Javascript
详解VUE2.X过滤器的使用方法
Jan 11 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
Jan 25 Javascript
微信小程序登录按钮遮罩浮层效果的实现方法
Dec 16 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
Jul 10 #Javascript
React之PureComponent的使用作用
Jul 10 #Javascript
详解在React.js中使用PureComponent的重要性和使用方式
Jul 10 #Javascript
echarts整合多个类似option的方法实例
Jul 10 #Javascript
详解使用Next.js构建服务端渲染应用
Jul 10 #Javascript
node.js中TCP Socket多进程间的消息推送示例详解
Jul 10 #Javascript
vue中$set的使用(结合在实际应用中遇到的坑)
Jul 10 #Javascript
You might like
PHP无刷新上传文件实现代码
2011/09/19 PHP
PHP Reflection API详解
2015/05/12 PHP
PHP使用数组依次替换字符串中匹配项
2016/01/08 PHP
探究Laravel使用env函数读取环境变量为null的问题
2016/12/06 PHP
PHP基于XMLWriter操作xml的方法分析
2017/07/17 PHP
2007/12/23更新创意无限,简单实用(javascript log)
2007/12/24 Javascript
javascript+canvas制作九宫格小程序
2014/12/28 Javascript
javascript操作select元素实例分析
2015/03/27 Javascript
js使用setTimeout实现定时炸弹的方法
2015/04/10 Javascript
XML文件转化成NSData对象的方法
2015/08/12 Javascript
漂亮! js实现颜色渐变效果
2016/08/12 Javascript
JavaScript中获取时间的函数集
2016/08/16 Javascript
Vue.js 中的 $watch使用方法
2017/05/25 Javascript
Angular服务Request异步请求的实例讲解
2018/08/13 Javascript
快速解决vue-cli在ie9+中无效的问题
2018/09/04 Javascript
angular 服务的单例模式(依赖注入模式下)详解
2018/10/22 Javascript
vue-cli项目配置多环境的详细操作过程
2018/10/30 Javascript
微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
2019/05/22 Javascript
Vue项目接入Paypal实现示例详解
2020/06/04 Javascript
vue各种事件监听实例(小结)
2020/06/24 Javascript
基于elementUI竖向表格、和并列的案例
2020/10/26 Javascript
[43:47]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第一场 12.09
2020/12/11 DOTA
[04:45]DOTA2-DPC中国联赛正赛 iG vs LBZS 赛后选手采访
2021/03/11 DOTA
零基础写python爬虫之抓取百度贴吧并存储到本地txt文件改进版
2014/11/06 Python
中粮集团旗下食品网上购物网站:我买网
2016/09/22 全球购物
Lentiamo比利时:便宜的隐形眼镜
2020/02/14 全球购物
全球最大的瓷器、水晶和银器零售商:Replacements
2020/06/15 全球购物
几个MySql的面试题
2013/04/22 面试题
建筑公司文秘岗位职责
2013/11/29 职场文书
实习单位指导教师评语
2014/12/30 职场文书
于丹讲座视频观后感
2015/06/15 职场文书
初中团委工作总结
2015/08/13 职场文书
《祁黄羊》教学反思
2016/02/20 职场文书
检举信的写法
2019/04/10 职场文书
golang http使用踩过的坑与填坑指南
2021/04/27 Golang
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python