AngularJS: как установить одно входное значение из другого и пройти проверку, как если бы оно было введено пользователем?

Я использую angular 1.3.0rc2, и я пытаюсь иметь поле ввода при размытии, установить другое поле ввода, как если бы оно было введено пользователем.

Если на вводе, который я пытаюсь установить, существует только синхронный валидатор, а не валидаторы debounce или async, все всегда работает так, как ожидалось, когда я делаю что-то вроде:

myForm.username.$setViewValue('some value');
myForm.username.$render();

Однако все работает не так, как ожидалось, когда на вводе, который я пытаюсь установить, существует либо асинхронный валидатор, либо средство устранения дребезга, и когда ввод, который я пытаюсь установить, находится в недопустимом состоянии.

Я создал следующий plunkr, чтобы продемонстрировать свои беды. Попробуйте установить значение "Полное имя" и посмотрите, что произойдет с полем Имя пользователя, которое я также хочу установить на размытие поля Полное имя поле. Когда поле Имя пользователя находится в недопустимом состоянии, изменение значения Полное имя и последующее снятие фокуса с поля не обновляет Имя пользователя, поскольку я ожидать.

http://plnkr.co/edit/h1hvf79W8ovqAlNLpBvS

Итак, мой вопрос: как я могу установить одно поле ввода из другого таким образом, чтобы оно работало надежно и действовало так, как будто пользователь сам ввел этот новый ввод (таким образом, пройдя через валидаторы и соответственно обновив значение модели)?


person jsdw    schedule 25.09.2014    source источник


Ответы (2)


Попробуйте это, оно должно изменить имя пользователя, когда вы размываете полное имя.

Plunkr

ngModel

HTML

Full Name:
<input name="fullName" ng-model="fullName" test-validator change-field="username" />
User Name:
<input name="username" ng-model="username" required />

JS

angular.module("testApp",[]).controller("testCtrl", function($scope) {  


}).directive('testValidator', ['$sce', function ($sce) {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function (scope, element, attrs, ngModel) {
      if(!ngModel) return;

      element.on('blur', function () {
        scope.$apply(read);
      });

      function read() {
        if(attrs.changeField) {
          var field = attrs.changeField;
          scope.myForm[field].$setViewValue(element.val());
          scope.myForm[field].$render();
        }
      }
    }
  }
}])
person jassok    schedule 25.09.2014
comment
Здравствуйте, спасибо за публикацию ответа. К сожалению, ваш ответ не использует асинхронную проверку и т. Д., И поэтому не решает проблему, с которой я столкнулся. Я отредактировал ваш плункер, добавив асинхронный валидатор, и проблема возникает снова: > - person jsdw; 26.09.2014
comment
Есть хороший шанс, что я думаю об этом неправильно, но я предполагаю, что вы хотите, чтобы пользователь ввел свое полное имя, чтобы он использовал его как свое имя пользователя, но прежде чем они это сделают, сделайте запрос к серверу, чтобы убедиться, что имя пользователя не занято и соответствует критериям проверки? Однако попробуйте это, посмотрите, поможет ли это. plnkr.co/edit/dAD6sWmE9tOhBR1ONAnk?p=preview - person jassok; 26.09.2014
comment
Попробуйте щелкнуть, а затем отключить первый ввод в вашем plunkr пару раз, когда второй ввод становится недействительным;) Другая проблема заключается в том, что теперь мой хороший asyncValidator привязан к установке значения элемента именно таким образом, что далеко не идеально, если Я хочу повторно использовать его в другом месте. - person jsdw; 26.09.2014
comment
Мое основное намерение состоит в том, чтобы одно поле обновляло другое как если бы пользователь сам ввел значение. Это означает, что если поле недействительно, значение модели, указанное из ng-model, должно стать неопределенным, как это происходит, когда пользователь вводит неверный ввод в поле. Именно это требование привело меня к попытке $setViewValue и т. д., а не просто обновлению значения модели поля имени пользователя, когда поле полного имени размыто (что не оставляет значение модели неопределенным, если оно становится недействительным). Я чувствую, что это должно быть возможно как-то :) - person jsdw; 26.09.2014

Итак, основная проблема, которую мы хотим здесь решить, заключается в том, что установка пользователем входных данных, которые оказываются недействительными, приводит к тому, что базовое значение модели устанавливается равным undefined, в то время как программная установка входных данных в недопустимое состояние не приводит к этому.

Это было непоследовательно, и поэтому я пытался найти способ обойти это. Оказывается, решение не так просто, как хотелось бы (см. https://github.com/angular/angular.js/issues/9295)

Однако вместо этого было предложено обратное решение, которое включает использование ngModelOptions в прилагаемой форме (или для каждого ввода, но это больше хлопот) с «allowInvalid», установленным в true. Это означает, что в модели по-прежнему будут установлены недопустимые значения, а не в этом случае значение модели очищается.

Учитывая, что модель теперь всегда устанавливается независимо от достоверности, я могу вернуться к более простым средствам программной установки одного поля из другого - просто установить значение базовой модели, и оно ведет себя идентично тому, как если бы пользователь сам установил значение :)

снова демонстрация plunkr с асинхронным валидатором на втором входе:

http://plnkr.co/edit/lkDN4qLbbkN79EmRrxsY?p=preview

посмотрите, как модель оказывается одинаковой независимо от того, установлено ли второе входное значение вручную или задано из первого ввода, независимо от валидности и использования асинхронного валидатора, по желанию :)

person jsdw    schedule 26.09.2014