将日期时间选择器连接到AngularJS

4

我需要使用angular和bootstrap创建一个带有日期和时间的输入框。我发现了这个日期时间选择器,它看起来正是我需要的 - 在一个字段中同时包含日期和时间,并阻止用户进行错误的编辑。我编写了一个指令,日期选择器也开始工作了,但它改变了视图而模型并没有改变... 我还尝试了onSelect,但仍然没有任何反应。

<div class="container container-fluid" ng-controller="Ctrl1">
2+2={{2+2}}, var1={{var1}}
    <form class="form-horizontal" novalidate name="form" ng-submit="submit()">
    <div class="well">
        <div id="date" class="input-append" datetimez ng_model="var1">
            <input data-format="MM/dd/yyyy HH:mm:ss PP" type="text" id="input1" name="input1" ng_model="var1"></input>
    <span class="add-on">
      <i data-time-icon="icon-time" data-date-icon="icon-calendar">
      </i>
    </span>
        </div>
    </div>
</form>

</div>

js

var project = angular.module('project',['ui.bootstrap']);

project.directive('datetimez', function() {
    return {
        restrict: 'A',
        require : 'ngModel',
        link: function(scope, element, attrs, ngModelCtrl) {
            $(function(){
                element.datetimepicker({
                    dateFormat:'dd/MM/yyyy hh:mm:ss',
                    language: 'pt-BR',
                    onSelect:function (date) {
                        //alert('zz');
                        ngModelCtrl.$setViewValue(date);
                        scope.$apply();
                    }
                });
            });
        }
    };
});

project.controller('Ctrl1', ['$scope', '$rootScope',  function(scope, rootScope){

    scope.var1="123";

}]);

如何解决连接问题?

我复制了所有代码和文件,但日期对话框没有出现(这是两个文件的截图http://img5.imageshack.us/img5/8231/9xbp.png)。在此处可以找到代码:http://jsfiddle.net/sLmyz/。 - Sol
在输入更改的操作日期和屏幕中,但var1仍然是旧值。http://img62.imageshack.us/img62/3882/5enm.png - Sol
这并没有明确回答你的问题,但是UI Bootstrap项目中包含一些日期选择器的指令。 - JeffryHouser
他们将日期和时间分开(同时也允许用户输入错误的字符),而我需要一个带有输入过滤的字段。 - Sol
还有另一个Angular的日期时间选择器指令,可以在https://github.com/zhaber/datetimepicker找到。 - Vitalii Fedorenko
显示剩余3条评论
3个回答

11

所以,问题如下:

  1. div id=date 元素中将 ng_model 改为 ng-model;
  2. input 元素中移除 ng_model 并实现 ngModelCtrl.$render 函数,以便将模型更改呈现到元素中;
  3. 根据组件文档

唯一公开的事件是“changeDate”,它将在事件对象上公开“date”和“localDate”属性

因此,您需要其他方式处理更改事件,看看:

element.datetimepicker({
  dateFormat:'dd/MM/yyyy hh:mm:ss',
    language: 'pt-BR'
  }).on('changeDate', function(e) {
    ngModelCtrl.$setViewValue(e.date);
    scope.$apply();
  });

这里是一个可工作的 Plnkr

一些额外的提示:

  1. 如前所述,删除内部的ng-model并实现ngModelCtrl.$render来处理模型更改
  2. 使用template属性来封装组件的内部元素

使用$render的一个非常简单的示例:

var picker = element.data('datetimepicker');

ngModelCtrl.$render = function() {
  if (ngModelCtrl.$modelValue) {
    picker.setLocalDate(ngModelCtrl.$modelValue);
  } else {
    picker.setLocalDate(null);
  }
}

"感谢!“并实现 ngModelCtrl.$render 来处理模型更改”是什么意思?ngModelCtrl.$setViewValue(e.date); 不够吗?实际上,我不理解新值是如何进入输入框的(我们将新值设置为具有'datetimez'指令的 div(它是 div 带有指令'datetimez')而不是输入框,那么日期值是如何跳到输入框的?这是因为 class="input-append" 吗?是 Bootstrap 执行了这个值的转移操作吗?" - Sol
回答你的两个问题,你可以使用$setViewValue在视图更改时更新模型。当模型发生变化时,您可以使用$render来更新视图。请参阅此处。我会在答案中添加一个小例子。 - Caio Cunha
刚刚添加了一个如何实现 ngModelCtrl.$render 函数的示例。 - Caio Cunha
好的,我明白我们为DIV元素设置了ViewValue,但是这个值如何传递到输入框中呢?输入框根本没有ngModel属性...它们通过css连接在一起 - id="input1"和class="input-append"? 还有一个关于输入框data-format="MM/dd/yyyy HH:mm:ss PP"属性的问题。如果我们在指令中硬编码dateFormat:'dd/MM/yyyy hh:mm:ss',那么它会被忽略吗? - Sol

2
晚了一步,但您总是可以使用这个。 Bootstrap-ui/datetime-picker 它使用 bootstrap-ui 中的日期选择器和时间选择器,而无需使用 jquery 或 moment.js。

1

你永远不应该在Angular中使用JQuery! - Kentonbmax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接