适用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. maven问题:如何不继承父工程的依赖

    在maven中,使用父工程来管理所有的依赖,当子工程只需要用到父工程的部分依赖,而不是所有依赖时,只需要在父工程的依赖中加入<dependencyManagement></depen ...

  2. web worker 扫盲篇

    什么是woker 官方的解释是这样的: worker是一个对象,通过构造函数Worker创建,参数就是一个js文件的路径:文件中的js代码将运行在主线程之外的worker线程: var jsFileU ...

  3. kafka 0.8.2 消息消费者 consumer

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  4. LAMP的搭建与简易配置(apache,php已module方式结合)

    测试所用环境:centos7.2 apache php 所在主机IP:9.110.187.120 mariadb 所在主机IP:9.110.187.121 第一部分:环境搭建 yum安装软件包 其中a ...

  5. Android6.0-运行时权限处理

    为什么需要有运行时权限? 大家都知道在Android6.0之前,权限在应用安装过程中只询问一次,以列表的形式展现给用户,如果点击取消(即不认可应用所申请的权限),则会取消应用的安装.而用户出于安装应用 ...

  6. VR全景智慧城市——商家的需求才是全景市场的核心竞争力

    消费者视角痛点:比如酒店消费行业,很多消费者在预订酒店过程中,都遇到过这样的场景:网上照片里酒店房间看着宽敞明亮,格调不凡,感觉非常喜欢,等真正推开房门插上房卡一看,却大失所望.在酒店行业,网上照片和 ...

  7. 安卓ios和angularjs相互调用解决首次调用ios传递标题失败的问题

    1.angular 调用客户端方法放在 try catch中 try { js_invoke.showShareDialog(angular.toJson(obj));  // 在这里放客户端的方法即 ...

  8. JDBC连接数据库程序

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

  9. SQL Server 在Alwayson上使用内存表"踩坑"

    200 ? "200px" : this.width)!important;} --> 介绍 因为线上alwayson环境的一个数据库上使用内存表.经过大概一个星期监控程序发 ...

  10. selenium+python浏览器窗口的切换

    1.首先需要知道当前浏览器中有多少个活动的窗口 >>> br.window_handles[u'{075a54ee-3d10-4c76-b56d-b645259bbd54}', u' ...