在uib-tab中,AngularJS uib-datepicker在第一次打开/关闭事件后不显示日历

时间:2015-12-30 21:08:59

标签: javascript angularjs datepicker angular-ui-bootstrap

版本:

  • Bootstrap 3.5.5
  • AngularJS 1.4.7
  • AngularUIB 0.14.3

我在选项卡页面中使用了一个uib-datepicker(使用uib-tabset)

<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方法调用中,我写入控制台以确保调用该方法。每当我选择日期选择器时(无论是否出现日历),控制器都会触发正确的方法。

我已将日期选择器从包装的tabset中取出,并且datepicker正常工作(每个选择显示日历)。我需要这个datepicker才能在我定义的uib-tabset中正常工作。

2 个答案:

答案 0 :(得分:7)

问题在于“范围继承”。角度范围基于js对象原型继承。

所以... $scope&lt; - { uib-tables scope }&lt; - { uib-tab scope } 第一次,{uib-tab范围}没有从{scope获取isDatePickerOpen属性,但在poput关闭后,{ uib-tab scope }将使自己的isDatePickerOpen超过false而后者更为优先考虑。函数openDatePicker正在更改$scope.isDatePickerOpen,但日历指令将从{ uib-tab scope }获取值。

如果在{{isDatePickerOpen}}代码后添加input,您就会看到它。第一次打开日历后,它总是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-router

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

2)访问父范围不推荐获取信息

controlller:

  $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/

答案 1 :(得分:1)

使用以下内容:

<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。