适用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. java 与操作系统同步问题(三)————父亲儿子女儿水果问题

    问题描述:父亲每次都会放一个水果在桌子上,女儿喜欢吃香蕉(只吃香蕉), 儿子喜欢吃苹果(只吃苹果).父亲每次只会随机往桌子上放一个水果(苹果或香蕉),儿子,女儿会来取.使用p.v操作来完成父亲.儿子. ...

  2. LiteIDE灰调配色方案

    说明 本文写于2017-04-03,使用LiteIDE X31(基于Qt 4.8.5),操作系统为Windows. 使用 LiteIDE下载后解压即可使用.配色方案的所有配置文件都位于liteide/ ...

  3. 你对SpringMvc是如何理解的?

    SpringMVC工作原理 SpringMvc是基于过滤器对servlet进行了封装的一个框架,我们使用的时候就是在web.xml文件中配置DispatcherServlet类:SpringMvc工作 ...

  4. python 字典的常见操作

    字典 字典的增删改查 字典的创建方式: # 创建字典类型 info = { 'name':'李白', ', 'sex':'男' } msg = { 'user01':'Longzeluola', 'u ...

  5. JDBC连接数据库程序

    废话少说,看了尚学堂的视频以及某大神的博客,总结出以下.(本文以oracle数据库为例) 创建一个JDBC连接数据库的程序,需要着手做以下几件事情: 注意,这里边使用了java.sql.Stateme ...

  6. python基础操作_字符串操作_列表操作list

    #字符串可以通过下表取值,如下程序 names='java python' print(names[0],names[5]) #使用for循环轮询所有name值 ''' for name in nam ...

  7. python面向对象的编程

    self相当于在实例化类的过程中传入参数,实例化对象本身 静态方法,静态字段属于类,动态字段,动态方法输入每一个实例化的对象 类实例化的过程把一些属性,方法封装到一个实例化对象当中 动态字段,动态方法 ...

  8. 关于Dubbo分布式服务

    这篇文章写的详细,可参考 http://shiyanjun.cn/archives/1075.html

  9. MVC分层含义与开发方式

    真正的服务层是面向数据的,假想一切数据都是从参数获得 控制层是接受页面层数据,再传给服务层,然后将结果返回给页面层的(客户) 页面层是提交格式化的数据的(容易小混乱,无格式,所以要格式化,可以在中间加 ...

  10. 浅谈this那些事

    一直以来,对this的讨论都是热门话题.有人说掌握了this就掌握了JavaScript的80%,说法有点夸张,但可见this的重要性.本人至今也是记录了很多关于this的零碎笔记,今天就来个小结. ...