将 min- 和 maxDate 绑定到变量

Bind min- and maxDate to variable

经过漫长的一天试图弄清楚 AngularJS 指令,我终于让我的日期选择器工作了,现在唯一让它变得完美的是最小和最大日期的实时变化。

Business case: I want to select a date when I started working on a project. Then I realize I selected the wrong date and that the project started later. I change the project's startdate and also want to correct the date I started working at it.

在那种情况下,使用我当前的代码,日期选择器中的 minDate 仍设置为旧项目的开始日期。

鉴于我的以下(工作)状态,是否有一种简单的方法可以做到这一点?

(我不知道如何让这个在 jsfiddle 左右播放,因为这是一个更大的项目的摘录,我还不知道它的所有依赖关系,我只是从 AngularJS)

在主 HTML 文件中,我这样调用我的自定义日期选择器:

<custom-date-picker
                 input-model="selectedProfile.startDate"
                 min-date="project.startDate"
                 max-date="project.endDate"
>
<custom-date-picker>

这是js中的指令部分:

.directive('customDatePicker', () => {
                return {
                    restrict: 'E',
                    templateUrl: 'assets/directives/custom-date-picker.html',
                    scope: {
                        inputModel: '=',
                        minDate: '=',
                        maxDate: '=',
                    },
                    controller: $scope => {
                        if ($scope.minDate && $scope.maxDate) {
                            $scope.dateOptions = {
                                maxDate: $scope.maxDate,
                                minDate: $scope.minDate,
                                startingDay: 1
                            };
                        }
                    },
                    link:
                        function (scope) {
                            scope.inputModel ? scope.inputModel = new Date(scope.inputModel) : false;
                        }
                }
            }

最后是指令 url 中引用的模板:

<input type="text"
       class="form-control"
       ng-model="inputModel"
       datepicker-options="dateOptions"
       uib-datepicker-popup="dd.MM.yyyy"
/>

(附带问题:$scope 中的 $ 似乎是必要的 - 是真的吗? - 为什么?)

你可能可以使用 AngualrJs 实现你想要的 $broadcast, $emit, and $on. 当日期改变时,你可以用新日期 $broadcast 或 $emit 事件,然后使用 $on 来更新你的日期输入。

我自己用Angular Date Range Picker实现了这个功能;下面是我的指令的代码。

.directive("fieldDate", ["$parse", function($parse) {
        return {
            restrict: "A",
            require: "ngModel",
            link: function($scope, elem, attrs, ngModel) {
                ngModel.$formatters.push(function(mv) {
                    if (mv == null) {
                        return null;
                    }
                    return DateUtil.format(new Date(mv.year, mv.month - 1, mv.day), "MM/dd/yyyy");
                });
                ngModel.$parsers.push(function(vv) {
                    if (StringUtil.isBlank(vv)) {
                        return null;
                    }
                    var date = DateUtil.parse(vv, "mm/dd/yy");
                    return DateUtil.toDateObj(date);
                });


                elem.daterangepicker({
                    "showDropdowns": true,
                    "linkedCalendars": false,
                    singleDatePicker: true,
                    autoUpdateInput: false,
                    "opens": "center",
                    "drops": "up"
                })
                    .on("apply.daterangepicker", function(ev, picker) {
                        $scope.$applyAsync(function() {
                            $parse(attrs.ngModel).assign($scope, DateUtil.toDateObj(picker.startDate.toDate()));
                        });
                    });
            }
        };
    }

指令底部的 .on() 函数从 daterangepicker 库接收名为 apply.daterangepicker 的事件,并将该值分配给我的模型。


对于你的附带问题,$scope 中需要 $ 的原因是因为 Angular 使用它来防止内置服务和对象与由定义的服务和对象之间的命名冲突开发商。 Reference

一位朋友告诉我神奇的 AngularJS 功能叫做 .$watch :D

事实证明这很简单,我只是在控制器中添加了这些行并且它起作用了:

$scope.$watch(
    function(scope) { return scope.minDate },
    function(newValue) {
        $scope.minDate ? $scope.dateOptions["minDate"] = new Date(newValue) : false;
    }
);

Reference

编辑多个变量,我使用的就是这种情况:

$scope.$watchGroup(
    ["minDate", "maxDate"],
    function (newValues) {
        $scope.minDate ? $scope.dateOptions["minDate"] = new Date(newValues[0]) : false;
        $scope.maxDate ? $scope.dateOptions["maxDate"] = new Date(newValues[1]) : false;
    }
);