【问题标题】:Bootstrap DateTimePicker with AngularJS: Passing directive ngModel value to controller使用 AngularJS 引导 DateTimePicker:将指令 ngModel 值传递给控制器
【发布时间】:2016-11-22 14:06:58
【问题描述】:

我正在尝试使用如下所示的自定义指令获取角度引导 datetimepicker 输入值。我能够获得指令中的值。如何在角度控制器中访问此指令范围值。

HTML

    <div class='input-group date'  id='datetimepickerId' datetimez ng-model="dueDate" >
          <input type='text'  class="form-control" />
    </div>

控制器

App.directive('datetimez', function(){
    return {
        require: '?ngModel',
        restrict: 'A',
        link: function(scope, element, attrs, ngModel){
            if(!ngModel) return;  
            ngModel.$render = function(){
                element.find('#datetimepickerId').val( ngModel.$viewValue || '' );
            };
            element.datetimepicker({ 
                format : 'YYYY-MM-DD HH:mm:ss'
            });
            element.on('dp.change', function(){
                scope.$apply(read);
            });
            read();
            function read() {
                var value = element.find('#datetimepickerId').val();
                ngModel.$setViewValue(value);
                console.log(scope.dueDate);
            }
        }
    };
});

App.controller('myController', ['$scope', function($scope) {
    console.log($scope.dueDate);
}]);

指令内的日志成功打印值。但是在控制器内部没有登录。

【问题讨论】:

  • 在第 20 行的 js $scope.dueDate 忘记了 $ 符号。
  • 如果我这样做,它会说 $scope 没有定义
  • datetimez ng-model="dueDate" 为什么在 div 标签中使用这个而不是在输入中使用?
  • 是控制器,指令的控制器,还是只是一个页面(不相关的)控制器?
  • 控制器初始化时,$scope.dueDate 中没有值。在日期更改时调用的函数中的输入和控制台中添加 ng-change。

标签: angularjs


【解决方案1】:

给你。

我查看了bootstrap datetimepicker 的文档,发现有两个实现。

  1. 带有一个图标,可单击并显示datetimepicker
  2. 另一个只有一个没有图标的文本框

对于第一个,您必须使用父 div 来启动插件,对于第二个选项,您必须使用文本框来启动插件

您使用了第二个选项,但使用父 div 以 directive 启动插件。

另外,div 元素不支持ngModel,因此指令应该与input 元素一起使用。

我已扩展您的指令以处理这两种情况,日期格式和其他选项也可以从 controller 传递。

你可以试试下面的sn-p。

var App = angular.module('App', []);

App.directive('datetimez', function(){
    return {
        require: '?ngModel',
        restrict: 'A',
        link: function(scope, element, attrs, ngModel){
            if(!ngModel) return;  
          
            ngModel.$render = function(){
                element.val( ngModel.$viewValue || '' );
            };
          
            function read() {
                var value = element.val();
                ngModel.$setViewValue(value);
                //console.log(scope.dueDate);
            }
            
            var options = scope.$eval(attrs.datetimez) || {};
            if(element.next().is('.input-group-addon')) {
              var parentElm = $(element).parent();
              parentElm.datetimepicker(options);
          
              parentElm.on('dp.change', function(){
                 scope.$apply(read);
              });
            } else {
              element.datetimepicker(options);
          
              element.on('dp.change', function(){
                 scope.$apply(read);
              });
            }
          
            read();
        }
    };
});

App.controller('myController', ['$scope', function($scope) {
  
    $scope.datePickerOptions = { 
       format : 'YYYY-MM-DD HH:mm:ss'
    };
    
    $scope.$watch('dueDate1', function(){
      console.log($scope.dueDate1);
    });
  
    $scope.$watch('dueDate2', function(){
      console.log($scope.dueDate2);
    });
}]);

angular.bootstrap(document, ['App']);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.16.0/moment.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<div class="container" ng-controller="myController">
    
    <div class="row">
        <div class='col-md-6'>
            <div class="form-group">
                <div class='input-group date' id='datetimepicker1'>
                    <input type='text' class="form-control" datetimez="datePickerOptions" ng-model="dueDate1" />
                </div>
            </div>
        </div>
    </div>
  
    <div class="row">
        <div class='col-md-6'>
            <div class="form-group">
                <div class='input-group date' id='datetimepicker1'>
                    <input type='text' class="form-control" datetimez="datePickerOptions" ng-model="dueDate2" />
                    <span class="input-group-addon">
                        <span class="glyphicon glyphicon-calendar"></span>
                    </span>
                </div>
            </div>
        </div>
    </div>
</div>

【讨论】:

  • 感谢您的精彩帖子。现在会检查并很快回来。
  • 我用了这个,但是 element.next(...).is 不是发生函数错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多