Ich habe eine Tabelle, die mit ng-repeat erstellt wird. Ich möchte jedem Element in der Tabelle eine Validierung hinzufügen. Das Problem ist, dass jede Eingabezelle denselben Namen hat wie die darüber und darunter liegende Zelle. Ich habe versucht, den {{$index}}
Wert zum Benennen der Eingaben zu verwenden, aber obwohl die Zeichenfolgenliterale in HTML korrekt erscheinen, funktioniert es jetzt.
Hier ist mein Code ab sofort:
<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>
Ich habe versucht, den {{}}
Index zu entfernen , aber das funktioniert auch nicht. Ab sofort funktioniert die Validierungseigenschaft der Eingabe ordnungsgemäß, die Fehlermeldung wird jedoch nicht angezeigt.
Hat jemand irgendwelche Vorschläge?
Bearbeiten: Zusätzlich zu den großartigen Antworten unten finden Sie hier einen Blog-Artikel, der dieses Problem ausführlicher behandelt: http://www.thebhwgroup.com/blog/2014/08/angularjs-html-form-design-part-2 /.
quelle
Antworten:
AngularJS verwendet Eingabenamen, um Validierungsfehler aufzudecken.
Leider ist es bis heute nicht möglich (ohne Verwendung einer benutzerdefinierten Direktive), einen Namen einer Eingabe dynamisch zu generieren. Wenn wir die Eingabedokumente überprüfen , können wir feststellen, dass das Namensattribut nur eine Zeichenfolge akzeptiert.
Um das Problem des dynamischen Namens zu lösen , müssen Sie ein inneres Formular erstellen (siehe ng-Formular ) :
Die andere Alternative wäre, eine benutzerdefinierte Direktive dafür zu schreiben.
Hier ist die jsFiddle, die die Verwendung der ngForm zeigt: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/
quelle
ng-form
DOM-Elemente, daher ist der Link zur anderen SO-Frage hier nicht relevant.ng-repeat
gebundentable tr
sindng-form="myname"
.Seit die Frage gestellt wurde, hat das Angular-Team dieses Problem gelöst, indem es die dynamische Erstellung von Eingabenamen ermöglicht hat.
Mit Angular Version 1.3 und höher können Sie dies jetzt tun:
Demo
Angular 1.3 führte auch ngMessages ein, ein leistungsfähigeres Tool zur Formularvalidierung. Sie können dieselbe Technik mit ngMessages verwenden:
quelle
$valid
Eigenschaft für die Eingabe falsch wirdfalse
Wenn Sie ng-form nicht verwenden möchten, können Sie eine benutzerdefinierte Direktive verwenden, die das Namensattribut des Formulars ändert. Platzieren Sie diese Direktive als Attribut auf demselben Element wie Ihr ng-Modell.
Wenn Sie andere Anweisungen in Verbindung verwenden, achten Sie darauf, dass für sie die Eigenschaft "terminal" nicht festgelegt ist, da diese Funktion sonst nicht ausgeführt werden kann (vorausgesetzt, sie hat die Priorität -1).
Wenn Sie diese Anweisung beispielsweise mit ng-Optionen verwenden, müssen Sie diesen einzeiligen Monkeypatch ausführen: https://github.com/AlJohri/bower-angular/commit/eb17a967b7973eb7fc1124b024aa8b3ca540a155
Ich finde es oft nützlich, ng-init zu verwenden, um den $ index auf einen Variablennamen zu setzen. Beispielsweise:
Dies ändert Ihren regulären Ausdruck in:
Wenn Sie mehrere verschachtelte ng-Wiederholungen haben, können Sie jetzt diese Variablennamen anstelle von $ parent. $ Index verwenden.
Definition von "Terminal" und "Priorität" für Direktiven: https://docs.angularjs.org/api/ng/service/ $ compile # directive-definition-object
Github-Kommentar zur Notwendigkeit eines Monkeypatch mit ng-Option: https://github.com/angular/angular.js/commit/9ee2cdff44e7d496774b340de816344126c457b3#commitcomment-6832095 https://twitter.com/aljohri/status/482935
AKTUALISIEREN:
Sie können diese Funktion auch mit ng-form ausführen.
quelle
Verwenden Sie die Anweisung ng-form innerhalb des Tags, in dem Sie die Anweisung ng-repeat verwenden. Sie können dann den von der Direktive ng-form erstellten Bereich verwenden, um auf einen generischen Namen zu verweisen. Beispielsweise:
Gutschrift an: http://www.benlesh.com/2013/03/angular-js-validating-form-elements-in.html
quelle
ng-form="formName"
zu dem Tag , das ng-repeat hat ... es hat wie ein Zauber funktioniert :)Komplexeres Beispiel mit "benutzerdefinierter Validierung" auf der Seite des Controllers hinzugefügt http://jsfiddle.net/82PX4/3/
quelle
Wenn ich mir diese Lösungen anschaue, ist die von Al Johri oben bereitgestellte meinen Bedürfnissen am nächsten, aber seine Anweisung war etwas weniger programmierbar als ich wollte. Hier ist meine Version seiner Lösungen:
Mit dieser Lösung können Sie einfach einen Namensgeneratorausdruck an die Direktive übergeben und die Sperrung der von ihm verwendeten Mustersubstitution vermeiden.
Ich hatte anfangs auch Probleme mit dieser Lösung, da sie kein Beispiel für die Verwendung in Markups zeigte. Deshalb habe ich sie hier verwendet.
Ich habe ein vollständigeres Arbeitsbeispiel für Github .
quelle
Die Validierung funktioniert mit ng repeat, wenn ich die folgende Syntax verwende.
scope.step3Form['item[107][quantity]'].$touched
Ich weiß nicht, ob dies eine bewährte Methode oder die beste Lösung ist, aber sie funktioniertquelle
Aufbauend auf der Antwort von pkozlowski.opensource habe ich eine Möglichkeit hinzugefügt, dynamische Eingabenamen zu verwenden, die auch mit ngMessages funktionieren . Beachten Sie den
ng-init
Teil auf demng-form
Element und die Verwendung vonfurryName
.furryName
wird zum Variablennamen, der den Variablenwert für das Attributinput
' enthältname
.quelle
Es ist zu spät, aber vielleicht kann es jedem helfen
fromname[uniquname].$error
Beispielcode:
Siehe Arbeits Demo hier
quelle
Wenn Ihr ng-repeat $ index so funktioniert
und
wir müssen die ng-show im ng-muster zeigen
quelle
Es ist möglich und hier ist, wie ich dasselbe mit einer Tabelle von Eingaben mache.
Wickeln Sie den Tisch in eine Form wie diese
Dann benutze einfach das
Ich habe ein Formular mit mehrfach verschachtelten Anweisungen, die alle Eingaben, Auswahlen usw. enthalten. Diese Elemente sind alle in ng-Wiederholungen und dynamischen Zeichenfolgenwerten enthalten.
So verwenden Sie die Richtlinie:
Hinweis: Sie können die Zeichenfolgenverkettung hinzufügen und indizieren, wenn Sie möglicherweise eine Tabelle mit Eingaben serialisieren müssen. was ich getan habe.
Dies sollte viele Situationen bewältigen, in denen Sie einfach nicht wissen, wo sich das Formular befindet. Oder haben Sie verschachtelte Formulare, möchten diesen Eingabenamen jedoch aus irgendeinem Grund an zwei Formulare anhängen? Geben Sie einfach den Formularnamen ein, an den Sie den Eingabenamen anhängen möchten.
Was ich wollte, war eine Möglichkeit, Eingaben, die ich nie erfahren werde, dynamische Werte zuzuweisen und dann einfach $ scope.myFormName. $ Valid aufzurufen.
Sie können alles hinzufügen, was Sie möchten: mehr Tabellen, mehr Formulareingaben, verschachtelte Formulare, was immer Sie wollen. Übergeben Sie einfach den Formularnamen, anhand dessen Sie die Eingaben überprüfen möchten. Fragen Sie dann beim Senden des Formulars, ob $ scope.yourFormName. $ Gültig ist
quelle
Dadurch wird der Name in der ng-Wiederholung separat in der Formularvalidierung angezeigt.
Ich hatte jedoch Probleme, es in der Validierungsnachricht nachzuschlagen, sodass ich ein ng-init verwenden musste, um eine Variable als Objektschlüssel aufzulösen.
quelle
Hier ein Beispiel, wie ich das mache, ich weiß nicht, ob es die beste Lösung ist, aber es funktioniert perfekt.
Zuerst Code in HTML. Schauen Sie sich die ng-Klasse an, sie ruft die Funktion hasError auf. Beachten Sie auch die Namensdeklaration der Eingabe. Ich benutze den $ Index, um verschiedene Eingabenamen zu erstellen.
Und jetzt ist hier die hasError-Funktion:
quelle
Meine Anforderungen waren etwas anders als die, die in der ursprünglichen Frage gestellt wurden, aber ich hoffe, ich kann jemandem helfen, der das gleiche Problem hat wie ich.
Ich musste definieren, ob ein Feld erforderlich war oder nicht, basierend auf einer Bereichsvariablen. Also musste ich im Grunde setzen
ng-required="myScopeVariable"
(was eine boolesche Variable ist).quelle