适用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. ElasticSearch的Marvel更新license

    Marvel安装的时候需要申请一个license,否则只有30天的使用时间,到期后最多保存7天的监控数据,为了造成不必要的监控数据丢失,建议安装的同时注册一个lincense,方法如下: 1.     ...

  2. .net开源权限管理系统

    有业务请加QQ 245747009 源码地址:http://git.oschina.net/sunzewei/EIP 一.更新记录1.更新日期:2017-02-24 00:00:002.更新内容: 版 ...

  3. socket聊天室(服务端)(多线程)(TCP)

    #include<string.h> #include<signal.h> #include<stdio.h> #include<sys/socket.h&g ...

  4. 【JAVAEE学习笔记】hibernate03:多表操作详解、级联、关系维护和练习:添加联系人

    一.一对多|多对一 1.关系表达 表中的表达 实体中的表达 orm元数据中表达 一对多 <!-- 集合,一对多关系,在配置文件中配置 --> <!-- name属性:集合属性名 co ...

  5. 事件总线(Event Bus)知多少

    源码路径:Github-EventBus 简书同步链接 1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对发布-订阅模式的一种实现.它是一种集 ...

  6. 在Quo.js下Tap和singleTap的区别

    前两天上网搜开发手机页面的JS,看到了Quo.js下载下来后来看了一下,支持的触屏手势挺多的,在一般的开发中应该够用了,更让我喜欢它的一点是它跟JQ差不多(虽然功能不如JQ强大但是语法基本一致).这就 ...

  7. sqlmap用户手册 [详细]

    当给sqlmap这么一个url的时候,它会: 1.判断可注入的参数 2.判断可以用那种SQL注入技术来注入 3.识别出哪种数据库 4.根据用户选择,读取哪些数据 sqlmap支持五种不同的注入模式: ...

  8. 最短路径Floyd算法【图文详解】

    Floyd算法 1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被 ...

  9. python入门小记

    一.help python中的帮助手册,对于初学者,多多使用help,多看看原生注释-- 1.help的使用 1.命令需要使用双引号或者单引号括起来,不使用引号引起来会报错 2.类或者函数(方法)不需 ...

  10. php 面向对象的三大特性

    <?phpheader("Content-type:text/html;charset=utf-8");/*封装目的:为了使类更加安全做法:1.将成员变量变成私有2.做一个成 ...