2016-05-24 2 views
1

Как сбросить поле ввода с помощью Angularjs при нажатии клавиш backspace/delete?Как сбросить поле ввода с помощью Angularjs при нажатии клавиш backspace/delete?

Я использовал это awesome directive, и он отлично сработал, за исключением случаев, когда пользователь очищает поле с помощью клавиши backspace или delete. Затем проверки не позволяют пользователю отправить форму (используя Chrome v.50.0.2661.102).

Я пробовал изменить директиву, но безуспешно. Буду признателен за любую оказанную помощь.

Вот директива с моими изменениями в el.bind():

angular.module(myApp) 
.directive('resetField', 
function resetField($compile, $timeout) { 
return { 
    require: 'ngModel', 
    scope: {}, 
    transclusion: true, 
    link: function (scope, el, attrs, ctrl) { 
     // limit to input element of specific types 
     var inputTypes = /text|search|tel|url|email|password/i; 
     if (el[0].nodeName !== "INPUT") 
      throw new Error("resetField is limited to input elements"); 
     if (!inputTypes.test(attrs.type)) 
      throw new Error("Invalid input type for resetField: " + attrs.type); 

     // compiled reset icon template 
     var template = $compile('<i ng-show="enabled" ng-mousedown="reset()" class="fa fa-times-circle"></i>')(scope); 
     el.addClass('reset-field'); 
     el.after(template); 

     scope.reset = function() { 
      ctrl.$setViewValue(null); 
      ctrl.$render(); 
      $timeout(function() { 
       el[0].focus(); 
      }, 0, false); 
      scope.enabled = false; 
     }; 

     el.bind('input', function() {  

      //I added this snippet since the directive on its own works so 
      // well, (thought scope.reset() above would do the trick) but it     
      //doesn't pass the validations... thus the remaining code 
      if (ctrl.$isEmpty(el.val())) {  
       scope.reset();  

       el[0].classList.remove('ng-dirty'); 
       el[0].classList.remove('ng-touched'); 
       el[0].classList.add('ng-pristine'); 
       el[0].classList.remove('ng-invalid-required'); 
       el[0].classList.add('ng-pristine'); 
       el[0].classList.add('ng-valid'); 

      } else { 
       scope.enabled = !ctrl.$isEmpty(el.val()); 
      } 
      scope.$apply(); 
     }) 
     .bind('focus', function() { 
      $timeout(function() { 
       scope.enabled = !ctrl.$isEmpty(el.val()); 
       scope.$apply(); 
      }, 0, false); 
     }) 
     .bind('blur', function() {   
      $timeout(function() { 
       scope.enabled = false;      
      }, 0, false); 

     }); 
    } 
}; 
}; 
); 

HTML-прежнему показывает нг-инвалида-требуется, так как в зависимости от поля, который был сброшен с забой не является нулевым.

Если я вызываю тот же самый вызов, что и нажатие на «X», почему он не работает одинаково?

ответ

1

Настройки действительности сохраняются на контроллере директивы ввода, поэтому удаление имен классов в HTML не имеет значения - они просто будут добавлены повторно в следующий дайджест.

Однако у вас есть доступ к ngModel controller в вашей директиве - передается в функцию link() как ctrl - так что вы можете вызвать методы там, чтобы вручную «установить» ее действительность/первозданность.

Вот краткий пример (пример первоначальной Директивы автора, плюс ваш выше код, модифицированный): http://jsbin.com/wuwezelige/1/edit?html,js,output

Я сделал требуется первое поле, и он также имеет ng-pattern регулярное выражение, которое должно соответствовать быть действительный. Когда вы возвращаетесь обратно, классы полей сбрасываются, чтобы отметить его как нетронутый и действительный

Надеюсь, это поможет.

Ссылка:
https://docs.angularjs.org/api/ng/type/ngModel.NgModelController https://docs.angularjs.org/api/ng/type/form.FormController

+0

Спасибо за помощь. Это имеет смысл. К сожалению, в моем случае это не сработало, потому что, как вы сказали, оно «снова добавляется в следующий дайджест». Это решило огромную тайну, потому что два входа зависели друг от друга, и всякий раз, когда я очищал один, а затем очищал другой, первый из них снова был недействительным. Забавно, что ng-click директивы отлично работает. Вы ответили на мой вопрос, хотя! – CMLee

+0

Хм. Функции $ setValidity и $ setPristine() на контроллере ngModel должны сделать эту работу. Можете ли вы отправить ссылку на свой код/​​демо, как у вас есть? – bags