2015-05-20 81 views
5

我正在使用此角度的日期時間選擇器。如何在angularJS中檢測引導datetimepicker更改事件

https://eonasdan.github.io/bootstrap-datetimepicker/

內部控制器的我:

$('#picker').datetimepicker(); 

在我的HTML我有:

<div id="#picker" > 
     <input type='text' style="font-size:10pt;" class="rptv-input" placeholder="Start Time" ng-model='adate' ng-change="datechange()" /> 
     <span class="input-group-addon"> 
      <span class="glyphicon glyphicon-calendar"></span> 
     </span> 
    </div>  

一切都是由一個控制器 「的AppController」 管理。 問題是,當我點擊日曆選擇日期時,它不會觸發任何「更改」事件(換句話說,datechange未被觸發)。如果我在ng-model「adate」上做手錶,它似乎也不會觸發它。如果我輸入文本框,那麼範圍變量就會改變。

如果用戶在選擇器中單擊日期以更改它,如何檢測文本框上的更改?

+0

其不同的庫,工作原理不同。不重複。 – Rolando

+0

更新了一個答案,以反映boostrap 3的事件,而不是jQuery UI –

+0

我有一個問題,我的viewmodel ng模型屬性不更新時,我從日曆中選擇日期(沒有主動寫入任何文本框) ,並且它仍然與ng-pristine角度指令保持一致,因爲它從不刷新新選定的值。有什麼需要考慮的? – CesarD

回答

4

這裏是邏輯的jist,但基本上你需要做一個指令,反過來創建datetimepicker本身。然後在功能change()函數中,您必須執行一個$apply(),這會觸發摘要循環並更新模型。

boostrap 3 datetimepicker event documentation

angular.module('yourApp') 
.directive('datetimepicker', function() { 
    return { 
     restrict: 'A', 
     require : 'ngModel', 
     link : function (scope, element, attrs, ngModelCtrl) { 

      element.datetimepicker({ 
       change:function (date) { 

        // Triggers a digest to update your model 
        scope.$apply(function() { 
         ngModelCtrl.$setViewValue(date); 
        }); 

       } 
      }); 
     } 
    } 
}); 

用途:

<input datetimepicker ng-model="adate" /> 
1

變化事件引導內觸發,所以你可能需要創建一個自定義指令您timepicker爲了趕上change事件像這樣:

.directive('yourDirective', function(){ 
         return{ 
          require: '?ngModel', 
          restrict: 'A', 
          link: function (scope,element,attrs, ngModel){ 
          if (!ngModel) return; 
          element.bind('change', function(e){ 
          //triggered event if change 
          }); 
          } 
         }; 
         }); 
0

我的指令和角度1。 5組件

 .directive('externalUpdate', ['$parse', function($parse) { 
      return { 
       link: function(scope, element, attrs){ 
        var setterFunc = $parse(attrs.ngModel).assign; 
        var func = scope.$eval(attrs.externalUpdate); 
        func(element, function(value) { 
         scope.$apply(function() { 
          setterFunc(scope, value); 
         }); 
        }); 
       } 
      }; 
     }]) 
     .component('datebox', { 
      bindings: { 
       size: '@@?', 
       name: '@@', 
       text: '@@', 
       model: '=', 
       classes: '@@?', 
       disabled: '=?', 
       time: '<?' 
      }, 
      controller: function() { 
       if (!this.size) { 
        this.col1 = '6'; 
        this.col2 = '6'; 
       } else { 
        var size = parseInt(this.size); 
        this.col1 = size.toString(); 
        this.col2 = (12 - size).toString(); 
       } 
       this.updateInput = function(element, setter) { 
        element.on("dp.change", function() { setter(element.val()); }); 
       } 
      }, 
      template: String.raw` 
       <div class="form-group"> 
        <label ng-if="$ctrl.col1!='0'" for="{{::$ctrl.name}}" class="col-md-{{::$ctrl.col1}} control-label">{{::$ctrl.text}}</label> 
        <div class="col-md-{{::$ctrl.col2}}"> 
         <input type="text" id="{{::$ctrl.name}}" ng-disabled="$ctrl.disabled" 
          class="form-control input-sm {{::$ctrl.classes}}" 
          ng-class="[{datepicker: $ctrl.time!=true},{datetimepicker: $ctrl.time==true}]" 
          ng-model="$ctrl.model" external-update="$ctrl.updateInput"> 
        </div> 
       </div>` 
     }) 
     .component('daterangebox', { 
      bindings: { 
       size: '@@?', 
       name: '@@', 
       text: '@@', 
       model: '=', 
       classes: '@@?', 
       disabled: '=?', 
       time: '<?' 
      }, 
      controller: function() { 
       if (!this.model || typeof this.model !== 'object') { 
        this.model = {}; 
       } 
       if (!this.size) { 
        this.col1 = '6'; 
        this.col2 = '6'; 
       } else { 
        var size = parseInt(this.size); 
        this.col1 = size.toString(); 
        this.col2 = (12 - size).toString(); 
       } 
       this.updateInput = function(element, setter) { 
        element.on("dp.change", function() { setter(element.val()); }); 
       } 
      }, 
      template: String.raw` 
       <div class="form-group"> 
        <label ng-if="$ctrl.col1!='0'" for="{{::$ctrl.name}}" class="col-md-{{::$ctrl.col1}} control-label">{{::$ctrl.text}}</label> 
        <div class="col-md-{{::$ctrl.col2}}"> 
         <div class="input-group"> 
          <input type="text" id="{{::$ctrl.name}}" ng-disabled="$ctrl.disabled" 
           class="form-control input-sm {{::$ctrl.classes}}" 
           ng-class="[{datepicker: $ctrl.time!=true},{datetimepicker: $ctrl.time==true}]" 
           ng-model="$ctrl.model.start" external-update="$ctrl.updateInput"> 
          <span class="input-group-addon input-sm">-</span> 
          <input type="text" ng-disabled="$ctrl.disabled" 
           class="form-control input-sm {{::$ctrl.classes}}" 
           ng-class="[{datepicker: $ctrl.time!=true},{datetimepicker: $ctrl.time==true}]" 
           ng-model="$ctrl.model.end" external-update="$ctrl.updateInput"> 
         </div> 
        </div> 
       </div>` 
     }) 
3

另一種選擇是

HTML:

 <div class="input-group date" id="dateTimePicker"> 
      <input type="text" class="form-control" /> 
      <span class="input-group-addon" ng-click="setDateTime()"> 
       <span class="glyphicon glyphicon-calendar"></span> 
      </span> 
     </div> 

控制器:

 $scope.setDateTime = function() { 

      $("#dateTimePicker").datetimepicker().on("dp.change", function (data) { 

       $scope.date = data.date._d; 

      }); 

     } 
-1

另一種簡單的方法。這爲我工作,

HTML

<input id="datepicker" type="text" class="form-control" data-ng-model="CurDate"/> 

jQuery代碼:

$("#datepicker").on("dp.change", function() { 
    $(this).trigger('change'); 
}); 

保持修復/單獨解決方法的想法...

還有一個角包裝(我的天堂」 t試過了。) https://gist.github.com/eugenekgn/f00c4d764430642dca4b

+0

您應該附加的更改事件是** changeDate **,如我的答案中所示。 –

1

對於您的應用程序的全局解決方案,我絕對支持上面的答案中顯示的自定義指令。但對於一次性:

根據當前的Bootstrap documentation,附加事件處理程序需要查找changeDate事件。見例如:

HTML標記:

<input class="date-picker" type="text" ng-model="$ctrl.model.date" /> 

角1.5.9控制器:

(function() { 

    'use strict' 

    var MyTestController = function() { 

     var vm = this; 

     vm.model = { 
      date: undefined 
     }; 

     (function initilize() { 
      $('.date-picker').datepicker({ 
       autoclose: true, 
       forceParse: false 
      }).on('changeDate', function (e) { 
       console.log('date was changed to: ' + e.date); 
      }); 
     })(); 
    }; 

    angular.module('myApp').component('myTest', { 
     controller: [MyTestController], 
     templateUrl: 'app/modules/my-test/view.html' 
    }); 
})(); 
0

我最近有同樣的問題(使用angularJS內檢測到的DateTimePicker改變事件https://eonasdan.github.io/bootstrap-datetimepicker/),實際上我的工作原理是@Mark Pieszak的相同想法,但有一些小的變化(我猜是因爲pluging版本)。如果您使用的是pluging的4版本,你需要使用上偵聽dp.change事件得到改變事件

app.directive('datetimepicker', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, element, attrs, ngModelCtrl) { 

      element.datetimepicker({ 
       defaultDate: new Date(), 
       maxDate: moment().endOf('d'), 
       locale: 'es', 
       format: 'DD/MM/YYYY', 
       widgetPositioning: { horizontal: 'right', vertical: 'bottom' } 

      }).on('dp.change', function (date) { 
       scope.$apply(function() { 
        ngModelCtrl.$setViewValue(date.date !== false ? date : null); 
       }); 
      }); 
     } 
    } 
}); 

和用法是一樣的。

<input datetimepicker name="yourInputName" id="yourInputName" type='text' class="form-control" ng-model="yourModelProperty" ng-required="yourRequiredExpression" ng-disabled="yourDisabledExpression" /> 

我作爲ngModelCtrl。$ setViewValue()的參數是因爲當我只通過的日期參數輸入是越來越有效,即使我離開空白的表達。

相關問題