AngularJS: Как мне вручную установить для ввода значение $ valid в контроллере?

92

Используя плагин TokenInput и используя встроенную проверку AngularJS formController.

Прямо сейчас я пытаюсь проверить, содержит ли поле текст, а затем установить поле действительным, если это так. Проблема с использованием плагина заключается в том, что он создает собственный ввод, а затем ul + li для stlying.

У меня есть доступ к addItem (formname) и моим возможностям в контроллере, мне просто нужно установить его на $ valid.

Разметка.

<form class="form-horizontal add-inventory-item" name="addItem">
     <input id="capabilities" name="capabilities" token-input data-ng-model="inventoryCapabilitiesAutoComplete" data-on-add="addCapability()" data-on-delete="removeCapability()" required>
     <div class="required" data-ng-show="addItem.capabilities.$error.required" title="Please enter capability."></div>
</form>

JS.

$scope.capabilityValidation = function (capability) {
  if (capability.name !== "") {
    addItem.capabilities.$valid = true;
    addItem.capabilities.$error.required = false;
  } else {
    addItem.capabilities.$valid = false;
    addItem.capabilities.$error.required = true;
  }
};

Я запускаю функцию capacityValidation, когда TokenInput что-то вводит и передает в объект.

РЕДАКТИРОВАТЬ:

Обнаруженная ng-модель на моем входе делает что-то и получает результаты автозаполнения, поэтому я не могу заставить ng-valid работать, поскольку он основан на модели.

$scope.inventoryCapabilitiesAutoComplete = {
  options: {
    tokenLimit: null
  },
  source: urlHelper.getAutoComplete('capability')
};

Я не писал эту реализацию автозаполнения, есть ли другой способ сделать это, где у меня будет доступ к атрибуту ng-model и переместить функцию модели в другое место?

Кристофер Маршалл
источник
1
Поскольку ваш плагин создает свой собственный ввод, и вы должны написать функцию для выполнения собственной проверки, почему бы просто не использовать для проверки собственное свойство $ scope: <div ... data-ng-show="capabilities_error" ...> Другими словами, есть ли причина, по которой вы хотите / должны использовать FormController?
Марк Райкок
2
Поскольку все мои другие формы используют его, я хотел бы сохранить контроль, который он дает. Созданный плагином ввод фактически устанавливает значение в моем исходном вводе, которое затем мне нужно проверить при проверке, но он не обновляет formController, когда есть введенное значение.
Кристофер Маршалл
Я специально сократил разметку, чтобы изолировать ввод. У меня есть еще несколько входов в той же форме.
Кристофер Маршалл
1
Ладно. Вы пытались addItem.capabilities.$valid = trueи / или устанавливали для addItem.capabilities. $ Error.required значение true или false в зависимости от ситуации?
Марк Райкок
Я пробовал и то, и другое. Я обновлю свой вопрос, чтобы показать вам. $ Valid и $ error.required отображаются как undefined в моей точке останова в контроллере, но addItem.capabilities все еще имеет данные.
Кристофер Маршалл

Ответы:

150

Вы не можете напрямую изменить срок действия формы. Если все входные данные-потомки действительны, форма действительна, если нет, то нет.

Что вам нужно сделать, так это установить действительность элемента ввода. Вот так;

addItem.capabilities.$setValidity("youAreFat", false);

Теперь ввод (и форма) недействителен. Вы также можете увидеть, какая ошибка вызывает аннулирование.

addItem.capabilities.errors.youAreFat == true;
Умур Контачи
источник
1
Что, если capabilitiesэто переменная? У меня есть массив, содержащий имена входов, и я хочу зациклить внутри массива и сделать их недействительными один за другим: /
lightalex
1
Что вы подразумеваете под переменной? Он напрямую привязан к самой форме, а не к значениям в форме. Он использует nameатрибут формы и атрибут ввода id. Это отличается от значений, установленныхngModel
Umur Kontacı
11
Я нашел решение, но имел в виду именно это:$scope.addItem['myVariableName'].$setValidity("youAreFat", false);
lightalex
После этого выясняется, что некоторые поля ввода больше не проверяются при изменении или размытии
Леонардо
4
В angular 1.4.7 мне пришлось добавить к этому коду префикс $ scope ..$scope.addItem.capabilities.$setValidity("youAreFat", false);
Graham T
61

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

Я наконец решил свою проблему с помощью этого кода, чтобы вручную установить для поля ввода значение ng-invalid (чтобы установить значение ng-valid, установите для него значение true):

$scope.myForm.inputName.$setValidity('required', false);
notMyName
источник
3
Я сделал то же самое, и он отлично работает. Но теперь у меня возникли проблемы с повторной проверкой того же поля. Он не переходит в измененное состояние, что очень раздражает. Я использую ng-model-options = "{updateOn: 'submit'}" для проверки при нажатии кнопки. Есть мысли по этому поводу?
OliverKK
1
@OliverKK вам нужно будет вызывать $setValidityсо trueвторым параметром, когда ввод действителен.
Бернхард Хофманн
10
не имеет смысла использовать rootcope, это должно быть просто scope
Ryan M
1
Я пробовал аналогичное решение, но обнаружил, что если я попытаюсь изменить значение элемента управления в форме, оно останется недействительным. В моем случае этот элемент управления является директивой с внутренним выбором. Если я установил недействительный для моей директивы (которая является формой ng), я не смогу удалить этот недопустимый статус.
Наоми
17

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

<input type="hidden" ng-model="vm.application.isValid" required="" />

В моем случае у меня был bool, допускающий значение NULL, при котором человек должен был выбрать одну из двух разных кнопок. если они ответят «да», объект добавляется в коллекцию и состояние кнопки изменяется. Пока не будут даны ответы на все вопросы (одна из кнопок в каждой из пар имеет щелчок), форма недействительна.

vm.hasHighSchool = function (attended) { 
  vm.application.hasHighSchool = attended;
  applicationSvc.addSchool(attended, 1, vm.application);
}
<input type="hidden" ng-model="vm.application.hasHighSchool" required="" />
<div class="row">
  <div class="col-lg-3"><label>Did You Attend High School?</label><label class="required" ng-hide="vm.application.hasHighSchool != undefined">*</label></div>
  <div class="col-lg-2">
    <button value="Yes" title="Yes" ng-click="vm.hasHighSchool(true)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == true}">Yes</button>
    <button value="No" title="No" ng-click="vm.hasHighSchool(false)" class="btn btn-default" ng-class="{'btn-success':  vm.application.hasHighSchool == false}">No</button>
  </div>
</div>
Джеймс Флеминг
источник
2

Все очень просто. Например: в вашем контроллере JS используйте это:

$scope.inputngmodel.$valid = false;

или

$scope.inputngmodel.$invalid = true;

или

$scope.formname.inputngmodel.$valid = false;

или

$scope.formname.inputngmodel.$invalid = true;

У меня все работает для разных требований. Ударьте, если это решит вашу проблему.

рахим.нагори
источник