Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs ng模式不适用于角度ui日期选择器_Angularjs_Angular Ui - Fatal编程技术网

Angularjs ng模式不适用于角度ui日期选择器

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

我想使用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="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
    使用
    unshift
    将$parser函数添加到
    $parsers
    数组的开头,因此我们还需要使用
    unshift
    将$parser放在
    datepicker
    的$parser之前
  • 正如您所提到的,
    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)
,以将状态重置为有效,现在似乎工作正常。如果为该指令编写了任何测试用例,请共享。。会有帮助的