适用Angular版本为:>=2。本文同样适用于Ionic这类的基于Angular实现的框架。

本文的思路也适用于控件显示的值和实际的值不一样时实现双向绑定。

1. 问题描述

在使用md2的datepicker控件时,遇到这样的问题,datepicker绑定的类型要求是Date类型,但是传输后台需要的类型是基于YYYY-MM-DD的日期字符串,但是Date类型默认转换为字符串是这样的:Fri Jun 02 2017 16:03:50 GMT+0800 (China Standard Time),导致后台没有正确的处理日期。

这个问题可以从后台处理,提供对应格式的反序列化,但是不是最佳方案。日期类型基于不同的语言区域平台,其默认生成的格式也是不一样的。

那么如何在前端从根源上处理呢?

2. 思路分析

刚开始考虑了两种方案:

1、通过声明gettersetter方法,绑定对应的gettersetter属性,但是这样会造成绑定时脏检查的死循环问题,所以否定这种方案;

2、通过Pipe,来实现将字符串转换为Date类型,实现绑定,但是这只能解决单向绑定,对于双向绑定也无能为力。

最后,考虑能否结合以上两种方案呢?

好的,结果是成功的,我们下面就来介绍如何一步一步的解决这个问题。

3. 问题解决

3.1. 示例model定义

这里定义一个People的示例model,只有一个属性birthday,为string类型。

import * as moment from 'moment';

export class People
{
birthday: string = ""; set ParseBirthday(val: Date){
this.birthday = moment(val).format("YYYY-MM-DD");
}
}

在这里我们生成了一个setter方法,用来将Date类型数据转换为对应格式的string类型。

3.2. 定义string类型单向绑定的pipe

代码如下:

import { Pipe, PipeTransform } from '@angular/core';
import * as moment from 'moment'; @Pipe({
name: 'stringToDate',
})
export class StringToDatePipe implements PipeTransform { transform(value: string, format: string, ...args) {
if(!format) format = "YYYY-MM-DD";
if(!!value && moment(value, format).isValid()){
var dVal = moment(value, format);
return dVal.toDate();
}
return null;
}
}

这个Pipe的目的就是将String类型转换为Date,这里可以传递一个format参数,为String类型对应的日期格式。

3.3. 最后我们进行一种改造的双向绑定

<md2-datepicker [ngModel]="p.birthday | stringToDate:'YYYY-MM-DD'" (ngModelChange)="p.ParseBirthday=$event" type='date' format='y-M-d'></md2-datepicker>

上面我们将原本基于[(ngModel)]的双向绑定,拆分成了一个单向绑定[ngModel]和一个ngModelChange事件处理,其中[ngModel]的单向绑定,是通过3.2节中定义的PipeString类型的birthday转换为Date类型进行绑定;然后当数据改变时,通过(ngModelChange)事件,通过setter方法将Date类型重新转换为String,并赋值给birthday

OK,问题解决了,完工。

附录

本文中使用了Moment.js来进行日期格式处理,可以通过如下命令安装相关依赖:

npm install moment --save

Angular表单控件需要类型和实际值类型不一致时实现双向绑定的更多相关文章

  1. Angular 从入坑到挖坑 - 表单控件概览

    一.Overview angular 入坑记录的笔记第三篇,介绍 angular 中表单控件的相关概念,了解如何在 angular 中创建一个表单,以及如何针对表单控件进行数据校验. 对应官方文档地址 ...

  2. vue表单控件绑定(表单数据的自动收集)

    v-model指令 你可以用 v-model 指令在表单控件元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素.尽管有些神奇 但 v-model 本质上不过是语法糖,它负责监听用户的 ...

  3. “此网页上的某个 Web 部件或 Web 表单控件无法显示或导入。找不到该类型,或该类型未注册为安全类型。”

    自从vs装了Resharper,看见提示总是手贱的想去改掉它.于是乎手一抖,把一个 可视web部件的命名空间给改了. 喏,从LibrarySharePoint.WebPart.LibraryAddEd ...

  4. angular 响应式自定义表单控件—注册头像实例

    1. 组件继承ControlValueAccessor,ControlValueAccessor接口需要实现三个必选方法 writeValue() 用于向元素中写入值,获取表单的元素的元素值 regi ...

  5. Angular:自定义表单控件

    分享一个最近写的支持表单验证的时间选择组件. import {AfterViewInit, Component, forwardRef, Input, OnInit, Renderer} from & ...

  6. MVC树控件,mvc中应用treeview,实现复选框树的多层级表单控件

    类似于多层级的角色与权限控制功能,用MVC实现MVC树控件,mvc中应用treeview,实现复选框树的多层级表单控件.最近我们的项目中需要用到树型菜单,以前使用WebForm时,树型菜单有微软提供的 ...

  7. AnjularJS系列2 —— 表单控件功能相关指令

    第二篇,表单控件功能相关指令. ng-checked控制radio和checkbox的选中状态 ng-selected控制下拉框的选中状态 ng-disabled控制失效状态 ng-multiple控 ...

  8. 基于CkEditor实现.net在线开发之路(3)常用From表单控件介绍与说明

    上一章已经简单介绍了CKEditor控件可以编写C#代码,然后可以通过ajax去调用,但是要在网页上面编写所有C#后台逻辑,肯定痛苦死了,不说实现复杂的逻辑,就算实现一个简单增删改查,都会让人头痛欲裂 ...

  9. 了解HTML表单之13个表单控件

    目录 传统控件 button select option optgroup textarea fieldset legend label 新增控件 datalist keygen output pro ...

随机推荐

  1. python爬虫从入门到放弃(五)之 正则的基本使用

    什么是正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是 事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符",这个"规则字符" 来表达对 ...

  2. Boosting决策树:GBDT

    GBDT (Gradient Boosting Decision Tree)属于集成学习中的Boosting流派,迭代地训练基学习器 (base learner),当前基学习器依赖于上一轮基学习器的学 ...

  3. Java异常类(Throwable)

    一.异常类体系 二.异常类由来与定义 [异常类的由来]:Java把程序在运行时出现的各种不正常情况也看成了对象, 提取属性和行为进行描述,比如异常名称,异常信息,异常发生位置,从而形成了各种异常类 [ ...

  4. Log POST Data in Nginx

    先编译Nginx的echo module: ./configure --add-module=./echo-nginx-module-0.54 make make install 可以在github上 ...

  5. Spring学习(17)--- 三种装配Bean方式比较

      基于XML配置 基于注解配置 基于Java类配置 Bean定义 <bean   id="..." class="..." /> @Compone ...

  6. 常用linux小工具介绍

    1.ctags(Generate tag files for source code)是vim下方便代码阅读的工具.尽管ctags也可以支持其它编辑器,但是它正式支持的只有VIM. ctags 最先是 ...

  7. Redis数据类型之List(三)

         前言:list即链表,它是一个能维持数据先后顺序的列表,便于在表的两端追加和删除数据,中间位置的存取具有O(N)的时间复杂度,是一个双向链表. 一.内部原理            redis ...

  8. [原创] 利用前端+php批量生成html文件,传入新文本,输出新的html文件

    本人因为要想自己写个小说网站练练手,在其中遇到的一些问题,将其解决方法总结出来,例如: 1:小说网站存储了大量的小说,每个小说主页都很相似,url不同,不是使用的history属性改写的,所以如果人工 ...

  9. Hibernate入门(五)

    一 Hibernate继承映射 我们可以将继承层次结构类与数据库的表映射. 1. 每个层次类一张表 这个层次结构有三个类,Employee是Regular_Employee和Contract_Empl ...

  10. Hibernate入门(一)

    一 Hibernate介绍 Hibernate 是一个开源.轻量级的ORM(对象关系映射)工具,该工具简化了数据创建.数据处理和数据访问,它是一种将对象映射到数据库中表的编程技术.ORM工具内部使用J ...