AngularJS uib日期选择器没有'在uib选项卡中,不要在第一次打开/关闭事件之后显示日历

AngularJS uib-datepicker doesn't display calendar after the first open/close event while in uib-tab

本文关键字:uib 第一次 显示 日历 之后 事件 选择器 日期 AngularJS 选项      更新时间:2023-09-26

版本:

  • 引导程序3.5.5
  • AngularJS 1.4.7
  • AngularUIB 0.14.3

我在选项卡页面中使用uib日期选择器(使用uib选项卡集)

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

控制器代码:

app.controller("ctrl", function($scope, heatMapSvc){
  $scope.isDatePickerOpen = false;
  $scope.openDatePicker = function(){
    $scope.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.isDatePickerOpen);
  };
});

选择输入时,日期选择器日历将按预期显示。然而,一旦我选择了一个日期,日期选择器日历将不会在选择时重新出现。我没有集中注意力,重新集中控制,什么都没有。在我的openDatePicker方法调用中,我向控制台写入以确保该方法被调用。每次我选择日期选择器(无论日历是否出现),控制器都会启动正确的方法。

我已经将日期选择器从它所包装的选项卡集中取出,并且日期选择器工作正常(显示每个选择的日历)。我需要这个日期选择器在我定义的uib选项卡集中正确工作。

"范围继承"中存在问题。Angular scopes基于js对象原型继承。

所以。。。$scope<-{ uib-tables scope }<-{ uib-tab scope }第一次,{uib-tab-scope}没有从$scope获得的isDatePickerOpen属性,但在poput关闭后,{ uib-tab scope }将获得自己的isDatePickerOpen,而不是等于false,后者更优先。函数openDatePicker更改$scope.isDatePickerOpen,但日历指令将从{ uib-tab scope }获取值。

你可以看到它是否会在input标签后添加{{isDatePickerOpen}}。第一次打开日历后,它总是false

解决方案

1)使用controllerAs语法 推荐

控制器:

  var vm = this;
  vm.isDatePickerOpen = false;
  vm.openDatePicker = function(){
    vm.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", vm.isDatePickerOpen);
  };

模板:

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='vm.isDatePickerOpen' ng-click='vm.openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

注意要使用此解决方案,必须使用controller as语法来声明控制器。

<body ng-controller="SettingsController1 as vm">
...
</body>

或者如果你使用ui路由器

$stateProvider.state('contacts', {
  templateUrl: '...',
  controller: function(){
    ...
  },
  controllerAs: 'vm'
})

2)访问父作用域不推荐用于信息

控制器:

  $scope.isDatePickerOpen = false;
  $scope.openDatePicker = function(){
    $scope.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.isDatePickerOpen);
  };

模板:

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='$parent.$parent.isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

3)使用对象可以使用,但第一次使用更好

控制器:

  $scope.status = {isDatePickerOpen : false};
  $scope.openDatePicker = function(){
    $scope.status.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.status.isDatePickerOpen);
  };

模板:

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='status.isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

可以将这篇文章的主题解释得更详细一些。http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/

通过以下操作实现此功能:

<input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-model='selectedDate' is-open='dateToImportIsOpen' ng-click='dateToImportIsOpen = !dateToImportIsOpen'/>

请注意,dateToImportIsOpen将被写入当前的$scope。