Angular-UI多个datepickers内幕形式控制器

时间:2013-08-16 14:59:02

标签: angularjs angular-ui

我正在创建一个包含多个angular-ui datepickers和一些输入数据的表单。 对于日期选择器,我创建了一个控制器和一个父表单控制器,如下面给出的示例。表单控制器具有包含日期​​选择日期的模型。

JS:

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

app.controller('dateCntrl', function($scope,$timeout){
    $scope.open = function() {
        $timeout(function() {
            $scope.opened = true;
        });
    };
});

app.controller('formCntrl', function($scope, $http){
    $scope.model = {name:'', startDate:'', endDate:''};
});

HTML:

<form ng-controller="formCntrl">
    <input type="text" id="name" placeholder="Name" ng-model="model.name" />
    <div ng-controller="dateCntrl">
        <input datepicker-popup="dd-MMMM-yyyy"  ng-model="model.startDate" id="startDate" type="text" />
        <button class="btn" ng-click="open()"><i class="icon-calendar"></i></button>
    </div>
    <div ng-controller="dateCntrl">
        <input datepicker-popup="dd-MMMM-yyyy" ng-model="model.endDate" id="endDate" type="text" />
        <button class="btn" ng-click="open()"><i class="icon-calendar"></i></button>
    </div>
</form>
  • 我是否正确地为datepicker设置了一个单独的控制器。这将作为所有日期输入的通用控制器
  • 如果是,是否可以使用通用方法将datepicker控制器中的数据绑定回父控制器中的模型日期(本例中为model.startDate,model.endDate)。
  • 有没有其他方法可以解决这个问题。

谢谢和问候。

3 个答案:

答案 0 :(得分:11)

应该阅读有关scope inheritance

的更多信息

可以使用$ parent

访问父作用域值
<form ng-controller="formCntrl">
    <input type="text" id="name" placeholder="Name" ng-model="model.name" />
    <div ng-controller="dateCntrl">
        <input datepicker-popup="dd-MMMM-yyyy"  ng-model="$parent.model.startDate" id="startDate" type="text" />
        <button class="btn" ng-click="open()"><i class="icon-calendar"></i></button>
    </div>
    <div ng-controller="dateCntrl">
        <input datepicker-popup="dd-MMMM-yyyy" ng-model="$parent.model.endDate" id="endDate" type="text" />
        <button class="btn" ng-click="open()"><i class="icon-calendar"></i></button>
    </div>
</form>

答案 1 :(得分:4)

我从这里的详细示例中获取了所有代码:http://angular-ui.github.io/bootstrap/#/datepicker&amp;把它包装成我自己的指令。这样我就可以将无限制的日期选择器放入我的页面,并为每个要绑定的模型指定模型。我不必管理传递重复设置,或设置唯一变量来跟踪“打开”状态,我只需要输入一行代码:

<div my-date-picker my-date-picker-model="myDate1"></div>
<div my-date-picker my-date-picker-model="myDate2"></div>
<div my-date-picker my-date-picker-model="myDate3"></div>

然后,用户可以切换每个日期选择器的打开/关闭,并将值更新为myDate1myDate2和&amp; myDate3恰当。现在,打开/关闭状态被封装在指令中,并且不在意。

为了实现该指令,我将'JS'选项卡的代码复制到它的控制器中,然后将'Markup'选项卡的代码复制到它的模板中。最后,我添加了1位代码来更新父作用域的值:

$scope.$watch('dt', function(newVal, oldVal) {
    $scope.myDatePickerModel = newVal;
});

在控制器的开头,我更改了$ scope.today来初始化父作用域的值,而不是使用系统时钟:

$scope.init = function() {
    $scope.dt = $scope.hxDatePickerModel;
};
$scope.init();

该指令使用隔离范围,并对定义父范围模型的属性进行双向绑定:

scope: {
    myDatePickerModel: '='
}

以下是该指令的完整代码:

app.directive('myDatePicker', function() {

    function link(scope, element, attrs) {
    }

    function controller($scope) {
       $scope.init = function() {
        $scope.dt = $scope.myDatePickerModel;
    };
    $scope.init();

        $scope.clear = function () {
            $scope.dt = null;
        };

        // Disable weekend selection
        $scope.disabled = function(date, mode) {
            return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
        };

        $scope.toggleMin = function() {
            $scope.minDate = $scope.minDate ? null : new Date();
        };
        $scope.toggleMin();

        $scope.open = function($event) {
            $event.preventDefault();
            $event.stopPropagation();

            $scope.opened = true;
        };

        $scope.dateOptions = {
            formatYear: 'yy',
            startingDay: 1
        };

        $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
        $scope.format = $scope.formats[0];

    $scope.$watch('dt', function(newVal, oldVal) {
        $scope.myDatePickerModel = newVal;
    });

    }

    return {
        restrict: 'A',
        templateUrl: 'datepicker.html',
        link: link,
        controller: controller,
        scope: {
            myDatePickerModel: '='
        }
    }
});

以下是datepicker.html的完整代码,该指令的模板:

<p class="input-group">
    <input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
      <span class="input-group-btn">
        <button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
      </span>
</p>

答案 2 :(得分:0)

其他解决方案,在$ rootScope中声明datepicker的open()方法,它可用于整个应用程序。

Html:

<div ng-app="myApp">
  <div ng-controller="DemoController">

        <div> 
        <input  type="text" name="salesEndDate" id = "salesEndDate"   datepicker-popup="dd-MM-yyyy"  ng-model="salesEndDate" datepicker-options="dateOptions"/>
        <button id="salesEndDateCal" ng-click="datePickerOpen('salesEndDate')"><i class="icon-calendar"></i></button> 
        </div>

    <div>
        <input  type="text" name="salesStartDate" id = "salesStartDate"   datepicker-popup="dd-MM-yyyy"  ng-model="salesStartDate"  datepicker-options="dateOptions"/>
         <button id="salesEndDateCal" ng-click="datePickerOpen('salesStartDate')"><i class="icon-calendar"></i></button> 
    </div>
 </div>
</div>

Javascript:

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


function DemoController($scope,$timeout,$rootScope) { 


$rootScope.datePickerOpen = function(id) {

             $timeout(function() {
                    $("#"+id).focus(); 
                });      
         };
}

jsfiddle link http://jsfiddle.net/angles_k/s7yZm/21/