Angularjs ng模式不适用于角度ui日期选择器
我想使用ng模式,使用Angular UI datepicker在输入字段上进一步强制使用日期格式。问题是当我这样做时,它总是显示无效Angularjs ng模式不适用于角度ui日期选择器,angularjs,angular-ui,Angularjs,Angular Ui,我想使用ng模式,使用Angular UI datepicker在输入字段上进一步强制使用日期格式。问题是当我这样做时,它总是显示无效 <p class="input-group"> <input type="text" datepicker-popup="MM/dd/yyyy" is-open="opened" close-text="Close" ng-model="someDate" class="form-control" placeholder
<p class="input-group">
<input type="text" datepicker-popup="MM/dd/yyyy" is-open="opened" close-text="Close"
ng-model="someDate" class="form-control" placeholder="mm/dd/yyyy"
ng-pattern="/^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/" required />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
如果我将相同的ng模式应用于普通输入字段(没有日期选择器),它将按预期工作
似乎有冲突,但我不确定是什么。有什么想法吗
更新:
是一个简单的plunker,用于按要求说明问题。在进一步挖掘之后,它似乎正在针对底层的Date
对象运行模式。但是,当我使用自定义指令格式化日期时,它会根据实际输入运行它
我看到的关于ng模式的唯一文档是input下的一个简短介绍。还有什么我可能遗漏的吗?正如我在评论中提到的,发生的是
日期选择器
指令正在将模型值从字符串
更改为日期
对象。当ngPattern
尝试验证Date
对象时,它将失败,因为Date
的字符串值与您正在使用的模式不匹配
您可以做的是创建自己的指令,该指令钩住以运行模式检查,然后根据值调用$setValidity()
$parsers
实际上是为这种类型的功能而构建的,您希望在ngModel
值上运行自己的自定义验证
在这些项目符号之后是一个指令,它将实现您想要的功能。在向您展示代码之前,我想解释一下指令中的逻辑:
- 为了添加自己的$parser,您必须在指令定义中添加对
的要求,以便访问ngModel
ngModelController
- 因为预期模式参数没有开头和结尾的斜杠,所以我在模式指令参数中删除了它们
将模型值从日期选择器
更改为字符串
。由于日期
使用datepicker
将$parser函数添加到unshift
数组的开头,因此我们还需要使用$parsers
将$parser放在unshift
的$parser之前datepicker
- 正如您所提到的,
指令将获取任何可以解析为日期的值,并将其用于模型。为了确保只使用与模式匹配的日期,对于与模式不匹配的日期,我将返回datepicker
(如文档中指定的)。我没有检查作为未定义的
对象输入的值,因为这意味着它是使用Date
小部件选择的datepicker
- 正如我刚才在前面的项目符号中提到的,如果值已经是
对象,我不会进行有效性检查,因为这意味着它是使用Date
小部件选择的,这意味着它是一个有效的日期datepicker
app.directive('awDatepickerPattern',function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope,elem,attrs,ngModelCtrl) {
var dRegex = new RegExp(attrs.awDatepickerPattern);
ngModelCtrl.$parsers.unshift(function(value) {
if (typeof value === 'string') {
var isValid = dRegex.test(value);
ngModelCtrl.$setValidity('date',isValid);
if (!isValid) {
return undefined;
}
}
return value;
});
}
};
});
html-确保不要忘记删除正则表达式定义中的开头和结尾斜杠:
aw-datepicker-pattern="^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$"
这是我的代码的更新版本
那么为什么ng模式又不起作用呢?
如果您没有注意到ng模式在与
datepicker
指令一起使用时不起作用的根本原因,则是因为datepicker
指令使用unshift
将其自己的ngModelController$parser添加到$parsers数组的开头,将型号值从字符串更改为日期
上述指令仅在需要日期时有效。我通过修改指令修复了它,如下所示:
ngModelCtrl.$setValidity('datep',isValid);
由于日期选择器在该指令之后运行,它将“日期”设置回有效状态。这里发布的其他解决方案的替代方案似乎是升级到2015-08-28发布的AngularJS 1.4.5:
只是猜测,但ng模式可能正在验证模型值,而不是视图值。在angular ui中使用日期选择器时,模型值将保存为日期
对象,而不是字符串
。在构建过程中是否使用html2js?如果是,它是什么版本?@JoseM我想到了(文档不是很清楚),但当我在另一个由日期对象支持的输入上复制时,它会工作,所以它似乎与日期选择器有关。@JoakimB我不熟悉html2js。。。它做什么?@aw04我看了一下plunker,也看了一下datepicker弹出窗口的代码,我知道发生了什么datepicker
确保模型值是一个Date
对象(只要它可以被解析),但ng模式只对字符串有效。我在考虑如何让您的需求发挥作用,但更重要的是,为什么您需要ng模式
验证datepicker
已经强制它成为有效的日期。请注意,我必须对该指令设置高优先级,以使其在我的环境中正常工作,与aw04相同。由于没有优先级,我总是在unshift函数中接收日期对象,因此我的字符串解析器从未执行。只是注意到一个问题:如果我手动输入无效日期,然后从datepicker下拉列表中选择有效日期,则验证仍然失败。显然,拾取有效值不会重置模型状态。也许这与Rory G所做的更改有关。无论如何,我在unshift
的最开始添加了一行ngModelCtrl.$setValidity('datep',true)
,以将状态重置为有效,现在似乎工作正常。如果为该指令编写了任何测试用例,请共享。。会有帮助的