javascript - Angular 的 JQ Lite 函数(triggerHandler 方法)在 Internet Explorer 11 中不起作用

标签 javascript jquery angularjs jquery-ui datepicker

我有一个 Angular.js 应用程序,它使用一些日历输入来选择日期范围。日历输入使用 jQuery UI 日期选择器。我非常清楚在 Angular 应用程序中使用 jQuery 模块可能产生的危险,并恳请我们避免在此线程中展开该讨论。

关于 Angular 和 jQuery UI 兼容性,我有几个函数和扩展,可以使日期选择器在 Angular 应用程序中很好地工作。

  1. 自定义日期选择器指令
  2. angular.element(el).triggerHandler('input')更新 Controller 范围的方法(否则只有 UI 发生变化 - 即使范围被监视,如果从 jQuery UI 事件触发,它也不会被消化)

我遇到的问题是 triggerHandler()正在更新除 IE 11 之外的每个浏览器中的 Controller 范围。我可以确认它可以在 IE Edge、Safari、Chrome、FireFox 和 Opera 中工作。

这是我的指令:

angular.module('trip.directives',[])
  .directive('ccDatePicker', function ($compile) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            $(element[0]).datepicker().on("change", function (e) {
                var date = element.val();
                scope.$apply( function () {
                    ngModelCtrl.$setViewValue(date);
                });
            });
        }
    };
})

这是我在 html 中调用的指令:

<p class="field date black">
    <input type="text" id="newtrip-date-from" class="form-control date datepicker date-from" name="date-from" id="date-from" placeholder="dd.mm.yyyy" ng-model="startModal.dateFrom" cc-date-picker />
    <input type="text" id="newtrip-date-to" class="form-control date datepicker date-to" name="date-to" id="date-to" placeholder="dd.mm.yyyy" ng-model="startModal.dateTo" cc-date-picker />
</p>

这是我的 javascript 日期选择器回调,它使用 angular.element(el).triggerHandler('input')更新我的 Controller 范围。这是适用于除 IE 11 之外的所有浏览器的部分:

    $('.datepicker').datepicker({
        minDate: 0,
        dateFormat: 'dd.mm.yy',
        onSelect: function(date) {
            var target = null;
            switch ( $(this).hasClass('date-from') ) {
                case true:
                    target = $(this).attr('id').split('from');
                    target = target[0] + "to";
                    $('#' + target).datepicker('option', 'minDate', date);
                    angular.element($(this)).triggerHandler('input');
                    break;
                case false:
                    target = $(this).attr('id').split('to');
                    target = target[0] + "from";
                    $('#' + target).datepicker('option', 'maxDate', date);
                    angular.element($(this)).triggerHandler('input');
                    break;
            }
        }
    });

如果有人知道在 IE 11 中更新此事件范围的解决方法,那将是非常有帮助的。谢谢!

最佳答案

所以我能够解决这个问题。如果有人偶然发现这个线程,以下是我解决问题的方法:

正如我所料,问题在于日期选择器没有发送更改事件。为了解决这个问题,我通过使用 angular.element() 获取元素的范围并运行 apply 函数来手动更新模型:

/* this first part checks for IE 11 */
if ( !(window.ActiveXObject) && "ActiveXObject" in window === true) {
    /* now we assign the element's angular scope to a variable */
    var $scope = angular.element($('input[name="date-from"]')).scope();
    /* and use that scope var to run an apply cycle */
    $scope.$apply(function () {
        /* here we set the value on the target model 
           using jQuery */
        $scope.startModal.dateFrom = $('input[name="date-from"]').val();
    });
}

最后,完全集成到日期选择器的 on select 回调中是这样的:

    $('.datepicker').datepicker({
        minDate: 0,
        dateFormat: 'dd.mm.yy',
        onSelect: function(date) {
            var target = null;
            switch ( $(this).hasClass('date-from') ) {
                case true:
                    target = $(this).attr('id').split('from');
                    target = target[0] + "to";
                    $('#' + target).datepicker('option', 'minDate', date);
                    if ( !(window.ActiveXObject) && "ActiveXObject" in window === true) {  // <= targets IE 11
                        var $scope = angular.element($('input[name="date-from"]')).scope(); // assign the elements scope to a var
                        $scope.$apply(function () {
                            $scope.startModal.dateFrom = $('input[name="date-from"]').val(); // sets the correct model value
                        });
                    } else {
                        angular.element($(this)).triggerHandler('input');
                    }
                    break;
                case false:
                    target = $(this).attr('id').split('to');
                    target = target[0] + "from";
                    $('#' + target).datepicker('option', 'maxDate', date);
                    if ( !(window.ActiveXObject) && "ActiveXObject" in window === true) {
                        var $scope = angular.element($('input[name="date-to"]')).scope();
                        $scope.$apply(function () {
                            $scope.startModal.dateTo = $('input[name="date-to"]').val();
                        });
                    } else {
                        angular.element($(this)).triggerHandler('input');
                    }
                    break;
            }
        }
    });

关于javascript - Angular 的 JQ Lite 函数(triggerHandler 方法)在 Internet Explorer 11 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34642486/

相关文章:

javascript - 使用 [attribute!=value] 和 addclass 的问题

javascript - 当前页面上的行数?

javascript - Angular 过滤器 + typescript

javascript - keyup后抓取输入值

javascript、jquery 和 jquery-ui 放置在页面底部时遇到的问题

ios - 由于协议(protocol)不匹配,Cordova 包装器中的 Angular Leaflet 不加载图 block

javascript - Angular UI 路由器抽象模板

javascript - 如何使用 Javascript/jQuery 在 Wordpress 主题模板上设置 cookie,然后在不同的模板中显示 cookie 值(如果已设置)

javascript - 使用 JQuery 添加 HTML

javascript - 在 ExpressJS Generator 中,Views 文件夹有什么用?