Обработка кнопки очистки IE с привязкой к AngularJS

IE имеет "X" в каждом текстовом входе, который очищает ввод. Однако при нажатии этой кнопки, когда он очищает текстовое поле, он не обновляет модель Angular, к которой привязан вход.

<input type="text" ng-model="name" />

См. http://jsfiddle.net/p5x1zwr9/ для примера поведения.

См. http://youtu.be/LFaEwliTzpQ для видео о поведении.

Я использую IE 11.

EDIT: похоже, решение для нокаута, но я не знаю, как применить его к AngularJS: Обрабатывать кнопку очистки IE 9 и 10 с привязкой к нокауту

UPDATE: Джонатан Сампсон помог мне понять, что это действительно работало в версиях AngularJS до 1.3.6, так что это может быть новая ошибка Angular.

UPDATE: Открытая проблема: https://github.com/angular/angular.js/issues/11193

Ответы

Ответ 1

Кнопка X в формах ввода является родной для IE10 +, и вы ничего не можете с этим сделать, но только спрячьте ее с помощью CSS:

input[type=text]::-ms-clear {
   display: none;
}

Затем вы можете создать свою собственную директиву для имитации такого поведения. Просто создайте интервал, расположите его внутри входа и добавьте ng-click к нему, что очистит значение модели ввода.

Ответ 2

Я создал эту директиву Angular для ввода текстовых элементов, которая вручную вызывает событие изменения элемента(), когда нажата кнопка очистки ( "X" ). Это поставило проблему в нашем проекте. Я надеюсь, что это поможет другим.

angular.module('app')
    .directive('input', function () {
        return {
            restrict: 'E',
            scope: {},
            link: function (scope, elem, attrs) {

                // Only care about textboxes, not radio, checkbox, etc.
                var validTypes = /^(search|email|url|tel|number|text)$/i;
                if (!validTypes.test(attrs.type)) return;

                // Bind to the mouseup event of the input textbox.  
                elem.bind('mouseup', function () {

                    // Get the old value (before click) and return if it already empty
                    // as there nothing to do.
                    var $input = $(this), oldValue = $input.val();
                    if (oldValue === '') return;

                    // Check new value after click, and if it now empty it means the
                    // clear button was clicked. Manually trigger element change() event.
                    setTimeout(function () {
                        var newValue = $input.val();
                        if (newValue === '') {
                            angular.element($input).change();
                        }
                    }, 1);
                });
            }
        }
    });

Благодаря этому ответу (Событие запускается при очистке ввода текста в IE10 с четким значком) для кода JavaScript для обнаружения щелчка кнопки очистки.

Ответ 3

Решение, с которым я столкнулся, не обновляет модель сразу, как удаление X и реализация вашего собственного решения. Оно действительно решает, что мне нужно. Все, что я сделал, это добавить опции ng-model для включения размытия. Поэтому, когда ввод размыт, он обновит значение области.

<input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur'}"  />

Ответ 4

Я смог решить это, используя следующую директиву - полученную из ответа 0x783e выше. Это может обеспечить лучшую совместимость с более поздними версиями angular. Он должен работать с часами или парсерами в дополнение к ng-изменению.

angular
    .module('yourModuleName')
    .directive('input', FixIEClearButton);

FixIEClearButton.$inject = ['$timeout', '$sniffer'];

function FixIEClearButton($timeout, $sniffer) {
    var directive = {
        restrict: 'E',
        require: '?ngModel',
        link: Link,
        controller: function () { }
    };

    return directive;

    function Link(scope, elem, attr, controller) {
        var type = elem[0].type;
        //ie11 doesn't seem to support the input event, at least according to angular
        if (type !== 'text' || !controller || $sniffer.hasEvent('input')) {
            return;
        }

        elem.on("mouseup", function (event) {
            var oldValue = elem.val();
            if (oldValue == "") {
                return;
            }

            $timeout(function () {
                var newValue = elem.val();
                if (newValue !== oldValue) {
                    elem.val(oldValue);
                    elem.triggerHandler('keydown');
                    elem.val(newValue);
                    elem.triggerHandler('focus');
                }
            }, 0, false);
        });

        scope.$on('$destroy', destroy);
        elem.on('$destroy', destroy);

        function destroy() {
            elem.off('mouseup');
        }
    }
}

Ответ 5

Скрываясь с помощью CSS Вместо "type = text" используйте "type = search" в полях поиска. Для этого только входы, помеченные как "type = search", не будут иметь "X", но другие входы будут иметь "X", который требуется для многих других поля в IE.

input[type=search]::-ms-clear {
   display: none;
}

Ответ 6

<input type="text" ng-model="name" id="search" />

This solution works for me

$("#search").bind("mouseup", function(e){
  var $input = $(this),
      oldValue = $input.val();

  if (oldValue == "") return;

  // When this event is fired after clicking on the clear button
  // the value is not cleared yet. We have to wait for it.

  setTimeout(function(){

    var newValue = $input.val();
    if (newValue == ""){
$scope.name="";
$scope.$apply();

    }
  }, 1);

});