AngularJS: Jak ręcznie ustawić wejście na $ prawidłowe w kontrolerze?

92

Użycie wtyczki TokenInput i użycie wbudowanego w AngularJS walidacji formController.

W tej chwili próbuję sprawdzić, czy pole zawiera tekst, a następnie ustawić pole na prawidłowe, jeśli tak. Problem z używaniem wtyczki polega na tym, że tworzy ona swoje własne dane wejściowe, a następnie ul + li do ustawiania.

Mam dostęp do addItem (formname) i moich możliwości w kontrolerze, wystarczy ustawić go na $ valid.

Narzut.

<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;
  }
};

Uruchamiam funkcję capacityValidation, gdy TokenInput ma coś wprowadzonego i przekazanego do obiektu.

EDYTOWAĆ:

Okazało się, że ng-model na moim wejściu robi rzeczy i otrzymuje wyniki autouzupełniania, dlatego nie mogę zmusić ng-valid do pracy, ponieważ jest oparty na modelu.

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

Nie napisałem tej implementacji autouzupełniania, czy jest inny sposób, aby to zrobić, w którym miałbym dostęp do atr ng-model i przenieść funkcję modelu w inne miejsce?

Christophera Marshalla
źródło
1
Ponieważ twoja wtyczka tworzy własne dane wejściowe i musisz napisać funkcję, która przeprowadzi własną walidację, dlaczego nie użyć własnej właściwości $ scope również do walidacji: <div ... data-ng-show="capabilities_error" ...> Innymi słowy, czy istnieje powód, dla którego chcesz / musisz używać FormController?
Mark Rajcok
2
Ponieważ wszystkie moje inne formularze go używają, chciałbym zachować kontrolę, jaką daje. Dane wejściowe utworzone przez wtyczkę w rzeczywistości ustawiają wartość w moim oryginalnym wejściu, które muszę następnie sprawdzić w mojej walidacji, ale nie aktualizuje on formController, gdy jest wprowadzona wartość.
Christopher Marshall,
Celowo skróciłem znaczniki, aby odizolować wejście. Mam o wiele więcej wejść w tej samej formie.
Christopher Marshall,
1
W porządku. Czy próbowałeś addItem.capabilities.$valid = truei / lub ustawić addItem.capabilities. $ Error.required na true lub false?
Mark Rajcok
Próbowałem obu. Zaktualizuję moje pytanie, aby ci pokazać. Wartości $ valid i $ error.required są wyświetlane jako niezdefiniowane w moim punkcie przerwania w kontrolerze, ale addItem.capabilities nadal zawiera dane.
Christopher Marshall,

Odpowiedzi:

150

Nie możesz bezpośrednio zmienić ważności formularza. Jeśli wszystkie dane potomne są prawidłowe, formularz jest ważny, jeśli nie, to nie jest.

To, co powinieneś zrobić, to ustawić ważność elementu wejściowego. Jak tak;

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

Teraz dane wejściowe (a więc formularz) są nieprawidłowe. Możesz również sprawdzić, który błąd powoduje unieważnienie.

addItem.capabilities.errors.youAreFat == true;
Umur Kontacı
źródło
1
A co jeśli capabilitiesjest zmienną? Mam tablicę, która zawiera nazwy wejściowe i chcę zapętlić wewnątrz tablicy i ustawić je nieprawidłowo jeden po drugim: /
lightalex
1
Co masz na myśli mówiąc zmienna? Jest bezpośrednio powiązany z samą formą, a nie z wartościami w formie. Używa nameatrybutu formularza i atrybutu danych wejściowych id. Różni się to od wartości ustalonych przezngModel
Umur Kontacı,
11
Znalazłem rozwiązanie, ale o to mi chodziło:$scope.addItem['myVariableName'].$setValidity("youAreFat", false);
lightalex
Po tym wydaje się, że niektóre pola wejściowe nie są już sprawdzane przy zmianie lub rozmyciu
Leonardo
4
Na kątowym 1.4.7 i musiałem poprzedzić ten kod $ scope ..$scope.addItem.capabilities.$setValidity("youAreFat", false);
Graham T
61

Powyższe odpowiedzi nie pomogły mi w rozwiązaniu problemu. Po długich poszukiwaniach trafiłem na to częściowe rozwiązanie .

W końcu rozwiązałem mój problem z tym kodem, aby ręcznie ustawić pole wejściowe na ng-invalid (aby ustawić na ng-valid, ustaw je na `` true ''):

$scope.myForm.inputName.$setValidity('required', false);
notMyName
źródło
3
Zrobiłem to samo i działa świetnie. Ale teraz mam problemy z rewalidacją tego samego pola. Nie zmienia się w zmieniony stan, co jest bardzo irytujące. Używam ng-model-options = "{updateOn: 'submit'}", aby potwierdzić po kliknięciu przycisku. Jakieś przemyślenia na ten temat?
OliverKK
1
@OliverKK trzeba powoływać $setValiditysię truejako drugi parametr, gdy wejście jest ważny.
Bernhard Hofmann
10
nie ma sensu używanie rootscope, powinno to być tylko zakres
Ryan M
1
Próbowałem podobnego rozwiązania, ale problem, który znalazłem polega na tym, że jeśli spróbuję następnie zmienić wartość kontrolki w formularzu, pozostaje ona nieważna. W moim przypadku ta kontrola jest dyrektywą z wewnętrznym wyborem. Jeśli ustawię nieprawidłowy stan dla mojej dyrektywy (czyli ng-form), nie mogę usunąć tego nieprawidłowego statusu.
Naomi
17

Natknąłem się na ten post z podobnym problemem. Moja poprawka polegała na dodaniu ukrytego pola, aby zachować mój nieprawidłowy stan.

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

W moim przypadku miałem zerowalny bool, który osoba musiała wybrać jeden z dwóch różnych przycisków. jeśli odpowiedzą tak, jednostka zostanie dodana do kolekcji i stan przycisku ulegnie zmianie. Do czasu uzyskania odpowiedzi na wszystkie pytania (jeden z przycisków w każdej z par ma kliknięcie) formularz jest nieważny.

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>
James Fleming
źródło
2

To bardzo proste. Na przykład: w kontrolerze JS użyj tego:

$scope.inputngmodel.$valid = false;

lub

$scope.inputngmodel.$invalid = true;

lub

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

lub

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

Wszystko działa dla mnie na różne wymagania. Uderz, jeśli to rozwiąże twój problem.

rahim.nagori
źródło