angular2 表单拆成多个组件及提交验证问题

2023-11-02

 

angular2表单最常用的方法就是在input或者textarea里直接添加formControlName或者formGroupName进行数据双向绑定并验证。 

 1 <form [formGroup]="goodsFormInfo">      
 2    <input type="text" formControlName="book_file" readonly="" />   
 3    <!--或者-->  
 4    <dl formGroupName="book_isbn">
 5     <dt>
 6      <span>*</span>ISBN号:
 7     </dt>
 8     <dd>
 9      <input id="book_isbn1" td-focus="" formControlName="book_isbn1" [patterninput]="'^[0-9]+$'" class="isbn" type="text" maxlength="3" />
10      <span>-</span>
11      <input id="book_isbn2" td-focus="" formControlName="book_isbn2" [patterninput]="'^[0-9]+$'" class="isbn" type="text" maxlength="1" />
12      <span>-</span>
13      <input id="book_isbn3" td-focus="" formControlName="book_isbn3" [patterninput]="'^[0-9]+$'" class="isbn" type="text" maxlength="7" />
14      <span>-</span>
15      <input id="book_isbn4" td-focus="" formControlName="book_isbn4" [patterninput]="'^[0-9]+$'" class="isbn" type="text" maxlength="6" />
16      <span>-</span>
17      <input id="book_isbn5" td-focus="" formControlName="book_isbn5" [patterninput]="'^[0-9]+$'" class="isbn" type="text" maxlength="1" />
18      <p class="warn-mark" *ngIf="mesg('book_isbn1') || mesg('book_isbn2') || mesg('book_isbn3') || mesg('book_isbn4') || mesg('book_isbn5') || mesg('book_isbn')"> {{ mesg('book_isbn1') || mesg('book_isbn2') || mesg('book_isbn3') || mesg('book_isbn4') || mesg('book_isbn5') || mesg('book_isbn') }}</p>
19     </dd>
20    </dl>
21   </form>

不过最近遇到一个比较复杂的表单提交, 如果全部写在一个组件里,代码可读性太差,所以把表单拆成了多个组件,通过formControlName进行数据的双向绑定。

举个简单的例子(核心代码):

一、form表单-html代码

1   <dl>
2    <dt> 商品定时下架:</dt>
3    <dd>
4     <tl-goods-sold-out-timing formControlName="auto_off_date"></tl-goods-sold-out-timing>
5     <p class="color-grey">系统会在该时间自动执行下架</p>
6     <p class="warn-mark warn-date" *ngIf="mesg('auto_off_date')">{{mesg('auto_off_date')}}</p>
7    </dd>
8   </dl>
9  <button class="btn btn-blue" (click)="submit()">保存</button>
二、tl-goods-sold-out-timing子组件 - html代码
1   <div class="clearfix"> 
2    <tl-check-box [labelname]="'设定'" [(ngmodel)]="isChecking" (onselectedfn)="selectedFn($event)"></tl-check-box> 
3    <div class="position-relative"> 
4     <tl-calendar [calendarobj]="calendarObj" [(ngModel)]="startDate" (ngModelChange)="selectDate($event)"></tl-calendar> 
5    </div> 
6   </div>
看到这里一定很奇怪,为什么同时写了ngModel和ngModelChange,ngModelChange在ts文件里会用到,这个日历组件的值改变后会需要我们调用一个change事件的,往下看。
三、tl-goods-sold-out-timing子组件 - ts代码
import { Component, OnInit, Output, Input, EventEmitter, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { CalendarObj } from '../../../../../shared'
@Component({
  selector: 'tl-goods-sold-out-timing',
  templateUrl: './goods-sold-out-timing.component.html',
  styleUrls: ['./goods-sold-out-timing.component.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => GoodsSoldOutTimingComponent),
      multi: true
    }
  ]
})
export class GoodsSoldOutTimingComponent implements OnInit {
  public calendarObj: CalendarObj;
  public isChecking: boolean;
  public startDate: Date;
  private change = (value) => { };      // 重点
  constructor() {
    this.calendarInit();
  }
  ngOnInit() { }
  get auto_off_date() {      // 父组件的formControlName接收这块return的数据 get的auto_off_date名称和下面this.change(this.auto_off_date);括号中的值名称一样
    console.log(this.startDate);
    if (!this.isChecking) {
      return {
        date: '',
        set: this.isChecking
      }
    }
    return  {
      date: this.startDate ? this.formatDate(this.startDate) : '',
      set: this.isChecking
    }
  }
  registerOnChange(fn) {     
    this.change = fn;
  }
  registerOnTouched(fn) { }
  writeValue(value) {     //  初始时如果父组件有值传入,就从这里写入组件。
    console.log(value);
    if (!value) {
      this.isChecking = false;
    } else {
      this.startDate = new Date(value.substr(0, 10));  // startDate为日历组件数据de双向绑定
      this.isChecking = true;
      console.log(this.startDate);
    }
  }
  // check-box事件
  selectedFn(event) {
    this.change(this.auto_off_date);
  }
  // 日期改变
  selectDate(date) {      // 数据一但改变,就调用一次change事件,如果上面html文件中没有写ngModelChange,这里日期改变就无法传值给父组件
    console.log(date);
    this.startDate = date;
    this.change(this.auto_off_date);    
  }
  // 日期格式转化
  formatDate = function (date) {
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? '0' + m : m;
    var d = date.getDate();
    d = d < 10 ? ('0' + d) : d;
    return y + '-' + m + '-' + d;
  };
// 日历组件初始化
  calendarInit() {
    this.calendarObj = new CalendarObj();
    this.calendarObj.placeholder = '开始日期';
    this.calendarObj.readonly = true;
    this.calendarObj.yearNavigator = true;
    this.calendarObj.monthNavigator = true;
    this.calendarObj.showOtherMonths = true;
    this.calendarObj.style = { 'width': '93px' };
    this.calendarObj.inputStyle = { 'width': '93px', 'background-position': '87px 1px', 'border': '1px solid #c7c7c7' };
  }
}
四、form表单-ts代码
formControlName="auto_off_date"接收到数据后,我们需要验证一下数据。
  submit(){
   console.log(this.goodsFormInfo.value);   //  打印表单接收到的数据
   if(this.goodsFormInfo.valid){
   // 如果通过验证就提交
   }
  }
  // 表单验证 
  formInfoInit() {
    this.goodsFormInfo= this.fb.group({ 
      'auto_off_date': ['', [this.validDate()]], 
    })
  }
  mesg(field: string) {
    return this.formUtil.mesg(field);
  }
 // 错误提示
  private validMessages = { 
    'auto_off_date': { 'dateError': '请选择定时下架时间' }, 
  };
  // 验证 - 定时下架
  reqDate() {
    return ((control) => {
      console.log(control);
      if (control.value && control.value.set) {
        if (control.value.date == '') {
          return { dateError: false };
        } }
    });
  }

 

 
(本文原创,转载请注明出处!!)

 

转载于:https://www.cnblogs.com/yanliujun-tangxianjun/p/7605198.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

angular2 表单拆成多个组件及提交验证问题 的相关文章

  • 为什么 Eclipse 有时会对 JavaScript 中的数组数组发出警告?

    在 Eclipse 中 以下 JavaScript 行 var a1 1 2 3 4 生成警告 Type mismatch cannot convert from Number to any Type mismatch cannot con
  • 如何用js获取一个月的4个星期一?

    我正在构建一个图表 其中 x 轴应该是一个月的四个星期 我只想显示该月的四个星期一 我已经有了currentMonth和currentYear变量 而且我知道如何获取该月的第一天 我所需要的只是将一个月的四个星期一放入数组中 所有这些都在同
  • 如何删除事件监听器?

    下面是我的事件监听器代码 window addEventListener beforeunload function e if sessionStorage token abide call api 如果我想删除这个事件监听器 我该怎么办
  • moment.calendar() 没有时间

    我想使用不带时间的 moment calendar 选项 所以而不是 上周二下午 5 点 我想要 上周二 有人知道 Moment 现在是否有解决方案吗 我找到了这个小提琴http jsfiddle net nawxZ http jsfidd
  • jQuery - 将所有展开的文本包装在 p 标签中

    我遇到以下情况 以下代码被写入我的页面 div Some text here which is not wrapped in tags p Some more text which is fine p p Blah blah another
  • jqgrid 在编辑框中选择不正确的下拉选项值

    我正在使用表单编辑 表单中有两个选择框 一个选择框是国家 地区 另一个选择框是州 州选择框取决于所选的国家 地区 并将动态填充 例如 Country 美国 期权价值 1 英国 期权价值 2 美国的状态 阿拉巴马州 选项值 1 加利福尼亚州
  • 如何检测不渲染 .png 透明的浏览器

    我有这段代码可以根据一周中的某一天渲染图像 但在 IE6 及更低版本以及可能其他一些浏览器中 它不会呈现 png 不透明度 所以我想稍微改变一下 这样它就会检测到不渲染 alpha 透明度的浏览器 并告诉他们加载这个图像 img horar
  • 单击量角器中元素的给定坐标

    我想点击我的特定位置canvas元素 所以我编写了以下量角器代码 var canvas element by id canvas var clickCanvas function toRight toBottom browser actio
  • 如何处理 d3 中 Beeswarm 图中的碰撞?

    我一直在玩这个例子here https gf neocities org co2bs co2bee html一会儿 我想做的是突出显示图中的单个节点 圆圈 通过使用边框使其变大 稍后我也想在其中添加文本或字母 目前 我已经圈了Bhutan图
  • JavaScript:参数列表后缺少 )

    这个 JavaScript 产生一个错误 参数列表后缺少 在 firebug 中使用代码 我究竟做错了什么 功能d缺少左括号 answer after 不应该逃避 只需常规报价即可
  • JavaScript 逻辑赋值是如何工作的?

    在 javascript 中 如果我们有一些代码 例如 var a one var b q a alert b 逻辑 OR 运算符会将 a 的值分配给 b 并且警报将为 一 这仅限于作业还是我们可以在任何地方使用它 似乎空字符串被视为与未定
  • 如何在WebBrowser控件中注入Javascript?

    我试过这个 string newScript textBox1 Text HtmlElement head browserCtrl Document GetElementsByTagName head 0 HtmlElement scrip
  • 在js中检测浏览器的最佳方法

    JavaScript 中有很多浏览器检测方法 据我所知 使用navigator userAgent或检测特征 例如XMLHttpRequest 等等 谁能告诉我哪种方法最好 最有效 如果你真的需要知道什么browser他们正在使用 你主要需
  • apollo 客户端从存储中删除而不发生突变

    我需要通过 id 从本地存储中删除一条 记录 而不使用突变 因为服务器不支持突变 我尝试像这样手动访问商店 delete this apolloClient store getState apollo data 1112 这会删除记录 但是
  • 两个日期之间间隔 15 分钟 javascript

    问题 我需要将两个日期 时间戳之间的所有 15 分钟时隙 日期格式 2016 08 10 16 00 00 创建为 HH mm 格式的数组 其中分钟限制为 00 15 30 45 示例 中午 12 30 到下午 2 30 将 gt 12 3
  • 在部分渲染时执行 JavaScript

    我有一些 JavaScript 代码 我想在用户单击其文件夹之一后执行 它会触发 show 操作和 show js erb 从而呈 现部分内容 Show js erb 当用户单击其文件夹之一时触发 如下所示 body append 它成功注
  • React TypeError:x 不是函数

    我在子组件中从父组件调用函数 booksRefresh 但出现错误 类型错误 booksRefresh 不是函数 我不知道为什么 因为 booksRefresh 是一个函数 有人可以帮我解释为什么会出现这个错误吗 这是我的代码 import
  • 如何在 JavaScript 中从代理对构造 UTF-16 字符?

    以下计算 Unicode 代码点的 UTF 16 代理对 戴着医用口罩的脸 https emojipedia org face with medical mask 但是如何从代理对构造字符以在字符串中使用呢 const codepoint
  • 如何在 WebView 中添加 JavaScript 函数并稍后在提交 reCAPTCHA 时从 HTML 调用它

    我在 WebView 中添加一个 JavaScript 函数 如下所示 Kotlin val webView findViewById R id webview as WebView webView getSettings setJavaS
  • 将一维数组转换为二维数组[重复]

    这个问题在这里已经有答案了 我正在开发一个程序 我必须将文本文件中的值读入一维数组 我已经成功获取该一维数组中的数字 m1 1 2 3 4 5 6 7 8 9 但我希望数组是 m1 1 2 3 4 5 6 7 8 9 您可以使用此代码 co

随机推荐

  • 砝码称重——不同算法解决

    1 问题 砝码称重问题 设有1g 2g 3g 5g 10g 20g的砝码各若干枚 其质量 lt 1000g 求出用他们能称出的质量的种类数 不包括质量为0的情况 2 枚举法 算法思路 1 枚举不同砝码的个数 计算总重量 并将总重量对应的标志
  • Java学习总结-IO流的概念理解

    一 Java io流 的概念 流存在的意义 1 数据的传输量很大 2 内存有限 3 带宽有限 而Stream可以1点1点地逐步传输所有数据 这就是Stream存在的根本意义 想想我们是怎样下载1个大文件的 下载软件 例如x雷 并不会占用你内
  • IOS推送总结

    此文主要以证书生成配置为主 实现简单推送 部分截图与内容来自于互联网 若对大家有所帮助 还请给个赞O O 如有误 请指出 一起探讨 一 推送原理 Provider是指某个iPhone软件的Push服务器 APNS 是Apple Push N
  • Java中instanceof关键字的理解

    java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例 instanceof通过返回一个布尔值来指出 这个对象是否是这个特定类或者是它的子类的一个实例 用法 result object instanceof
  • linux宝塔命令

    安装宝塔 Centos安装脚本 yum install y wget wget O install sh http download bt cn install install sh sh install sh Ubuntu Deepin安
  • Linux中的Chrony时间同步服务

    目录 一 时间同步 1 概念 2 时间同步在运维工作中的作用 3 时间同步完成方法 1 NTP时间服务 centos 6 2 Chrony时间服务 二 Chrony时间服务 1 Chrony介绍 2 Chrony的优点 三 Chrony安装
  • shell脚本中grep时关于变量带双引号的小问题

    今天在写一个shell脚本的时候 有一个操作是使用grep命令在一个文件中搜索指定内容 指定内容存放在文件中 使用一个变量去获取文件中内容 再传到grep命令中去 这段代码如下 for target in cat content txt d
  • java游戏服务器开发需要学习的技术

    一 游戏服务器编程语言的选择 所谓的游戏服务器编程语言其实有很多 基本上任何一种语言都可以作为游戏服务器的编程语言 这需要根据自己游戏的类型和要求加以选择 比如C Java Erlang go等等 目前我用过的只有C 和Java 但是以Ja
  • 查看broker节点信息

    kafka查看broker节点信息可以进入zookeeper客户端中查看 运行zkCli sh进入客户端 输入ls 可以看到相关的节点 输入 ls broker ids 可以看到broker数
  • Hyperledger Fabric网络快速启动

    目录 1 网络服务配置 2 关联的docker compose base yaml 各Peer节点容器设置如下信息 3 被关联的Peer base yaml 4 启动网络 2 完成通道的创建 2 1将节点加入应用通道 更新锚节点 2 为什么
  • 第九章:C语言数据结构与算法初阶之堆

    系列文章目录 文章目录 系列文章目录 前言 一 堆的定义 二 堆的实现 三 堆的接口函数 1 初始化 2 销毁 3 插入 4 删除 5 判空 6 元素个数 四 堆应用的原理 五 堆排序 1 建堆 2 排序 六 堆的应用 TOPK 1 什么是
  • [Excel VBA]状态栏如何显示文字 ?

    本文译至 http itpro nikkeibp co jp atcl column 15 090100207 090100148 Application StatusBar 字符串 画面最下方的状态栏可以显示任意的字符串 显示的字符串可以
  • 生产数据实时同步到预生产

    生产数据库同步到预生产 实现实时同步 参见 MySQL binlog2sql 非主从实时同步 恢复误删数据 同步昨晚的备份 基于昨晚的全备 在预生产服务器添加定时执行此脚本 重置数据库 刷入昨晚的全备 0 4 bin sh scripts
  • 基于舒适性的速度规划。对路面进行分级,基于路面状况对舒适性的影响对速度进行规划

    基于舒适性的速度规划 对路面进行分级 基于路面状况对舒适性的影响对速度进行规划 建模仿真MATLAB Simulink编号 54150653898883414Hsvssvg
  • makefile找不到

    如果下载的代码执行make j时找不到makefile 需要自己生成 现在有makefile am sudo apt install automake libtool m4 autoconf autoconf autoreconf vif
  • 【random库与math库】python程序对一组随机数求平均值,标准差,中位数,离差,离差方,总体方差,样本方差,样本标准差

    基本统计值计算 使用random库生成随机数100个 1 100 的整数 同时借用math库进行了简单的计算 对生成的一组随机数求平均值 标准差 中位数 离差 离差方 总体方差 样本方差 样本标准差 计算公式如下 程序代码如下 from m
  • 单片机开发板sv32wb0x,C语言,创建websocket客户端

    本人参考大佬的代码移植进单片机 调试BUG后并且成功跑通 如果你不了解websocket协议建议参考Linux下c语言实验Websocket通讯 含客户端和服务器测试代码 我只是把这位大佬写的提取出我需要的 基于单片机lwip网络编程 本代
  • Docker私有镜像仓库harbor搭建

    Harbor搭建镜像仓库 文章目录 Harbor搭建镜像仓库 Harbor简述 系统环境与软件版本说明 安装docker 安装docker compose 安装Harbor 使用Harbor上传下载镜像基于http https协议 访问页面
  • GitHub:[亲测方法简单+有效] 成功解决 Failed to connect to github.com port 443: Timed out

    01 遇到的问题 使用以下命令 提交代码到远程仓库时 git push u origin master 遇到如下问题 fatal unable to access https github com xxx Failed to connect
  • angular2 表单拆成多个组件及提交验证问题

    angular2表单最常用的方法就是在input或者textarea里直接添加formControlName或者formGroupName进行数据双向绑定并验证 1