Mam tabelę utworzoną za pomocą ng-repeat. Chcę dodać walidację do każdego elementu w tabeli. Problem polega na tym, że każda komórka wejściowa ma taką samą nazwę jak komórka nad i pod nią. Próbowałem użyć {{$index}}
wartości do nazwania danych wejściowych, ale pomimo tego, że literały tekstowe w HTML wydają się poprawne, teraz działa.
Oto mój kod na teraz:
<tr ng-repeat="r in model.BSM ">
<td>
<input ng-model="r.QTY" class="span1" name="QTY{{$index}}" ng-pattern="/^[\d]*\.?[\d]*$/" required/>
<span class="alert-error" ng-show="form.QTY{{$index}}.$error.pattern"><strong>Requires a number.</strong></span>
<span class="alert-error" ng-show="form.QTY{{$index}}.$error.required"><strong>*Required</strong></span>
</td>
</tr>
Próbowałem usunąć {{}}
z indeksu, ale to też nie działa. W tej chwili właściwość walidacji danych wejściowych działa poprawnie, ale komunikat o błędzie nie jest wyświetlany.
Czy ktoś ma jakieś sugestie?
Edycja: Oprócz poniższych świetnych odpowiedzi, tutaj jest artykuł na blogu, który bardziej szczegółowo omawia ten problem: http://www.thebhwgroup.com/blog/2014/08/angularjs-html-form-design-part-2 /
źródło
Odpowiedzi:
AngularJS polega na nazwach danych wejściowych w celu ujawnienia błędów walidacji.
Niestety, na dzień dzisiejszy nie jest możliwe (bez użycia niestandardowej dyrektywy) dynamiczne generowanie nazwy wejścia. Rzeczywiście, sprawdzając dokumenty wejściowe , widzimy, że atrybut name przyjmuje tylko ciąg.
Aby rozwiązać problem `` dynamicznej nazwy '' , musisz utworzyć wewnętrzną formę (patrz ng-form ) :
Inną alternatywą byłoby napisanie w tym celu niestandardowej dyrektywy.
Oto jsFiddle pokazujący użycie ngForm: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/
źródło
ng-form
elementy DOM, więc link do drugiego pytania SO nie ma tutaj znaczenia.ng-repeat
związanytable tr
, musisz użyćng-form="myname"
attr.Odkąd zadano to pytanie, zespół Angular rozwiązał ten problem, umożliwiając dynamiczne tworzenie nazw wejść.
W Angular w wersji 1.3 i nowszych możesz teraz zrobić to:
Próbny
Angular 1.3 wprowadził również ngMessages, potężniejsze narzędzie do walidacji formularzy. Możesz użyć tej samej techniki z ngMessages:
źródło
$valid
właściwość dla wejścia jest niepoprawnafalse
Jeśli nie chcesz używać ng-form, możesz użyć niestandardowej dyrektywy, która zmieni atrybut name formularza. Umieść tę dyrektywę jako atrybut w tym samym elemencie co twój model ng.
Jeśli używasz innych dyrektyw w połączeniu, uważaj, aby nie miały ustawionej właściwości „terminal”, w przeciwnym razie ta funkcja nie będzie mogła działać (biorąc pod uwagę, że ma priorytet -1).
Na przykład, gdy używasz tej dyrektywy z ng-options, musisz uruchomić ten jeden wiersz monkeypatch: https://github.com/AlJohri/bower-angular/commit/eb17a967b7973eb7fc1124b024aa8b3ca540a155
Często uważam, że przydatne jest użycie ng-init do ustawienia indeksu $ na nazwę zmiennej. Na przykład:
Spowoduje to zmianę wyrażenia regularnego na:
Jeśli masz wiele zagnieżdżonych powtórzeń ng, możesz teraz używać tych nazw zmiennych zamiast $ parent. $ Index.
Definicja „terminala” i „priorytetu” dla dyrektyw: https://docs.angularjs.org/api/ng/service/ $ compile # Directive-definition-object
Komentarz Github dotyczący potrzeby ng-option monkeypatch: https://github.com/angular/angular.js/commit/9ee2cdff44e7d496774b340de816344126c457b3#commitcomment-6832095 https://twitter.com/aljohri/status/482963541520314
AKTUALIZACJA:
Możesz również sprawić, by działało to z ng-form.
źródło
Użyj dyrektywy ng-form wewnątrz tagu, w którym używasz dyrektywy ng-repeat. Następnie możesz użyć zakresu utworzonego przez dyrektywę ng-form, aby odwołać się do nazwy ogólnej. Na przykład:
Kredyt dla: http://www.benlesh.com/2013/03/angular-js-validating-form-elements-in.html
źródło
ng-form="formName"
do tagu, który ma powtórzenie ng ... zadziałało jak urok :)Dodano bardziej złożony przykład z „niestandardową walidacją” po stronie kontrolera http://jsfiddle.net/82PX4/3/
źródło
Patrząc na te rozwiązania, to, które przedstawił Al Johri powyżej, jest najbliższe moim potrzebom, ale jego dyrektywa była trochę mniej programowalna niż chciałem. Oto moja wersja jego rozwiązań:
To rozwiązanie pozwala po prostu przekazać wyrażenie generatora nazw do dyrektywy i pozwala uniknąć blokowania podstawiania wzorca, którego używał.
Miałem też początkowo problemy z tym rozwiązaniem, ponieważ nie pokazało ono przykładu użycia go w znacznikach, więc oto jak go użyłem.
Mam bardziej kompletny przykład roboczy na githubie .
źródło
walidacja działa z powtórzeniem ng, jeśli używam następującej składni
scope.step3Form['item[107][quantity]'].$touched
Nie wiem, czy jest to najlepsza praktyka lub najlepsze rozwiązanie, ale działaźródło
Opierając się na odpowiedzi pkozlowski.opensource , dodałem sposób na uzyskanie dynamicznych nazw wejść, które działają również z ngMessages . Zwróć uwagę na
ng-init
część nang-form
elemencie i użyciefurryName
.furryName
staje nazwę zmiennej, która zawiera wartość zmiennej dlainput
„sname
atrybut.źródło
Jest już za późno, ale może pomoże każdemu
fromname[uniquname].$error
Przykładowy kod:
Zobacz działające demo tutaj
źródło
Jeśli używasz ng-repeat $ index działa w ten sposób
i
musimy pokazać ng-show we wzorze ng
źródło
Jest to możliwe i oto jak robię to samo z tabelą wejść.
owinąć stół w taką formę
Następnie po prostu użyj tego
Mam formularz z wieloma zagnieżdżonymi dyrektywami, z których wszystkie zawierają dane wejściowe, zaznaczenia, itp ... Te elementy są zawarte w ng-powtórzeń i dynamicznych wartościach ciągów.
Oto jak korzystać z dyrektywy:
Uwaga: jeśli chcesz serializować tabelę danych wejściowych, możesz dodawać i indeksować do konkatenacji ciągów; co właśnie zrobiłem.
Powinno to rozwiązać wiele sytuacji, w których po prostu nie wiesz, gdzie będzie formularz. A może masz zagnieżdżone formularze, ale z jakiegoś powodu chcesz dołączyć tę nazwę wejściową do dwóch formularzy wyżej? Cóż, po prostu podaj nazwę formularza, do którego chcesz dołączyć nazwę wejściową.
To, czego chciałem, to sposób na przypisanie wartości dynamicznych do danych wejściowych, których nigdy nie poznam, a następnie wywołanie po prostu $ scope.myFormName. $ Valid.
Możesz dodać wszystko, co chcesz: więcej tabel, więcej danych wejściowych, zagnieżdżone formularze, cokolwiek chcesz. Po prostu podaj nazwę formularza, dla którego chcesz sprawdzić poprawność danych wejściowych. Następnie podczas przesyłania formularza zapytaj, czy $ scope.yourFormName. $ Jest prawidłowe
źródło
Dzięki temu nazwa w powtórzeniu ng pojawi się osobno w walidacji formularza.
Ale miałem problem z wyszukaniem go w komunikacie walidacji, więc musiałem użyć ng-init, aby rozwiązać zmienną jako klucz obiektu.
źródło
Oto przykład jak to robię, nie wiem, czy to najlepsze rozwiązanie, ale działa idealnie.
Najpierw kod w HTML. Spójrz na ng-class, wywołuje funkcję hasError. Spójrz także na deklarację nazwy wejścia. Używam indeksu $ do tworzenia różnych nazw wejściowych.
A teraz mamy funkcję hasError:
źródło
Moje wymagania były nieco inne niż te zadane w pierwotnym pytaniu, ale mam nadzieję, że mógłbym pomóc komuś, kto ma ten sam problem co ja.
Musiałem zdefiniować, czy pole było wymagane, czy nie na podstawie zmiennej zakresu .. Więc w zasadzie musiałem ustawić
ng-required="myScopeVariable"
(która jest zmienną boolowską).źródło