Biorąc pod uwagę listę pól wyboru powiązanych z tym samym formControlName
, w jaki sposób mogę utworzyć tablicę wartości pól wyboru powiązanych z formControl
, a nie po prostu true
/ false
?
Przykład:
<form [formGroup]="checkboxGroup">
<input type="checkbox" id="checkbox-1" value="value-1" formControlName="myValues" />
<input type="checkbox" id="checkbox-2" value="value-2" formControlName="myValues" />
<input type="checkbox" id="checkbox-3" value="value-2" formControlName="myValues" />
</form>
checkboxGroup.controls['myValues'].value
obecnie produkuje:
true or false
Co chcę, żeby wyprodukował:
['value-1', 'value-2', ...]
javascript
angular
checkbox
angular2-forms
ReactingToAngularVues
źródło
źródło
Odpowiedzi:
Z pomocą cichej odpowiedzi napisałem rozwiązanie, aby uzyskać wartości zamiast stanów w moim formBuilder.
Używam metody do dodawania lub usuwania wartości w formArray. To może być złe podejście, ale działa!
component.html
component.ts
Kiedy przesyłam formularz, na przykład mój model wygląda tak:
Brakuje tylko jednej rzeczy, funkcji do wypełnienia formularza formArray, jeśli Twój model ma już sprawdzone wartości.
źródło
myChoices: new FormArray([], Validators.required)
Oto dobre miejsce do korzystania z
FormArray
https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.htmlNa początek zbudujemy naszą tablicę kontrolek z
FormBuilder
rozszerzeniem lub nowym rozszerzeniemFormArray
FormBuilder
nowy FormArray
To dość łatwe, ale potem zmienimy nasz szablon i pozwolimy silnikowi szablonów obsłużyć sposób, w jaki łączymy się z naszymi kontrolkami:
template.html
Tutaj iterujemy nasz zestaw
FormControls
w naszymmyValues
FormArray
i dla każdej kontrolki wiążemy się[formControl]
z tą kontrolką, a nie zFormArray
kontrolką i<div>{{checkboxGroup.controls['myValues'].value}}</div>
produkuje,true,false,true
jednocześnie sprawiając, że składnia szablonu jest nieco mniej ręczna.Możesz użyć tego przykładu: http://plnkr.co/edit/a9OdMAq2YIwQFo7gixbj?p=preview do przeglądania
źródło
*ngFor="let control of checkboxGroup.controls['myValues'].controls ; let i=index""
Jest to znacznie łatwiejsze w Angular 6 niż w poprzednich wersjach, nawet jeśli informacje o polu wyboru są wypełniane asynchronicznie z interfejsu API.
Pierwszą rzeczą, którą należy sobie uświadomić, jest to, że dzięki
keyvalue
rurze Angular 6 nie musimy już jej używaćFormArray
, a zamiast tego możemy zagnieździćFormGroup
.Najpierw przekaż FormBuilder do konstruktora
Następnie zainicjalizuj nasz formularz.
Gdy nasze dane opcji pola wyboru są dostępne, iteruj je i możemy włożyć je bezpośrednio do zagnieżdżonego
FormGroup
jako nazwanegoFormControl
, bez konieczności polegania na tablicach wyszukiwania indeksowanych według liczb.Na koniec w szablonie musimy tylko iterować
keyvalue
pola wyboru: bez dodatkowychlet index = i
, a pola wyboru będą automatycznie ułożone w kolejności alfabetycznej: znacznie czystsze.źródło
const checkboxes = ..
poza foreach;)Jeśli szukasz wartości pól wyboru w formacie JSON
Pełny przykład tutaj .
Przepraszam za używanie nazw krajów jako wartości pól wyboru zamiast tych w pytaniu. Dalsze wyjaśnienie -
Utwórz FormGroup dla formularza
Niech każde pole wyboru będzie FormGroup zbudowane z obiektu, którego jedyną właściwością jest wartość pola wyboru.
Tablica FormGroups dla pól wyboru służy do ustawiania kontrolki dla „krajów” w formularzu nadrzędnym.
W szablonie użyj potoku, aby uzyskać nazwę kontrolki pola wyboru
źródło
Nie widzę tutaj rozwiązania, które całkowicie odpowiada na pytanie przy użyciu formularzy reaktywnych w pełnym zakresie, więc oto moje rozwiązanie na to samo.
Podsumowanie
Oto sedno szczegółowego wyjaśnienia wraz z przykładem StackBlitz.
FormArray
dla pól wyboru i zainicjuj formularz.valueChanges
obserwowalne, jest idealne, gdy chcesz, aby formularz wyświetlał coś, ale przechowywał coś innego w komponencie. Zamapuj wartościtrue
/false
na żądane wartości tutaj.false
wartości w momencie przesyłania.valueChanges
obserwowalnych.Przykład StackBlitz
Szczegółowe wyjaśnienie
Użyj FormArray, aby zdefiniować formularz
Jak już wspomniano w odpowiedzi oznaczonej jako poprawna.
FormArray
jest dobrym rozwiązaniem w takich przypadkach, w których chciałbyś uzyskać dane w tablicy. Więc pierwszą rzeczą, którą musisz zrobić, jest utworzenie formularza.Spowoduje to ustawienie początkowej wartości wszystkich pól wyboru na
false
.Następnie musimy zarejestrować te zmienne formularza w szablonie i iterować po
checkboxes
tablicy (NIE poFormArray
danych z pola wyboru), aby wyświetlić je w szablonie.Wykorzystaj obserwowalną wartość valueChanges
Oto część, której nie widzę w żadnej udzielonej tutaj odpowiedzi. W sytuacjach takich jak ta, w których chcielibyśmy wyświetlić wspomniane dane, ale przechowywać je jako coś innego,
valueChanges
obserwowalne są bardzo pomocne. KorzystanievalueChanges
możemy obserwować zmiany wcheckboxes
, a następniemap
ztrue
/false
wartości otrzymanych odFormArray
do żądanych danych. Zwróć uwagę, że nie zmieni to wyboru pól wyboru, ponieważ każda prawdziwa wartość przekazana do pola wyboru oznaczy je jako zaznaczone i odwrotnie.Zasadniczo mapuje
FormArray
wartości do oryginalnejcheckboxes
tablicy i zwracavalue
w przypadku, gdy pole wyboru jest oznaczone jakotrue
, w przeciwnym razie zwracafalse
. JestemitEvent: false
to ważne, ponieważ ustawienieFormArray
wartości bez niego spowodujevalueChanges
wyemitowanie zdarzenia tworzącego nieskończoną pętlę. UstawiającemitEvent
nafalse
, upewniamy się, żevalueChanges
obserwowalne nie wyemitują, gdy ustawimy tutaj wartość.Odfiltruj fałszywe wartości
Nie możemy bezpośrednio filtrować
false
wartości wFormArray
pliku, ponieważ spowoduje to zepsucie szablonu, ponieważ są one powiązane z polami wyboru. Dlatego najlepszym możliwym rozwiązaniem jest odfiltrowaniefalse
wartości podczas przesyłania. W tym celu użyj operatora spreadu.To w zasadzie odfiltrowuje fałszywe wartości z
checkboxes
.Anuluj subskrypcję valueChanges
Na koniec nie zapomnij zrezygnować z subskrypcji
valueChanges
Uwaga: Istnieje specjalny przypadek, w którym wartość nie może być ustawiona na
FormArray
invalueChanges
, tj. Jeśli wartość pola wyboru jest ustawiona na liczbę0
. Spowoduje to, że pole wyboru nie może być zaznaczone, ponieważ zaznaczenie pola wyboru ustawiFormControl
jako liczbę0
(wartość fałszywą), a zatem pozostawi niezaznaczone. Byłoby lepiej, aby nie używać liczby0
jako wartości, ale jeśli jest to wymagane, musisz warunkowo ustawić0
jakąś prawdziwą wartość, powiedzmy ciąg'0'
lub po prostu zwykły,true
a następnie przy przesyłaniu przekonwertować ją z powrotem na liczbę0
.Przykład StackBlitz
StackBlitz ma również kod, gdy chcesz przekazać domyślne wartości do pól wyboru, aby zostały oznaczone jako zaznaczone w interfejsie użytkownika.
źródło
TL; DR
To również mnie czasami uderzało, więc wypróbowałem zarówno podejście FormArray, jak i FormGroup.
W większości przypadków lista checkboxów znajdowała się na serwerze i otrzymywałem ją przez API. Ale czasami będziesz mieć statyczny zestaw pól wyboru ze wstępnie zdefiniowaną wartością. W każdym przypadku użycia zostanie użyty odpowiedni FormArray lub FormGroup.
Ze względu na prostotę wyobraź sobie, że masz prostą formę produktu za pomocą
Najpierw skonfigurowałem formularz z tylko nazwą produktu formControl. To jest wymagane pole.
Ponieważ kategoria jest renderowana dynamicznie, będę musiał dodać te dane do formularza później, gdy dane będą gotowe.
Istnieją dwa podejścia do tworzenia listy kategorii.
1. Form Array
To
buildCategoryFormGroup
zwróci mi FormArray. Pobiera również listę wybranych wartości jako argument, więc jeśli chcesz ponownie użyć formularza do edycji danych, może to być pomocne. W celu stworzenia nowego formularza produktu nie ma jeszcze zastosowania.Zauważyłem, że podczas próby uzyskania dostępu do wartości formArray. Będzie to wyglądało
[false, true, true]
. Aby uzyskać listę wybranych identyfikatorów, sprawdzenie z listy wymagało nieco więcej pracy, ale w oparciu o indeks tablicy. Nie brzmi to dla mnie dobrze, ale działa.Dlatego wymyśliłem używanie
FormGroup
w tym celu2. Grupa formularzy
Różnica w formGroup polega na tym, że przechowuje dane formularza jako obiekt, który wymagał klucza i kontrolki formularza. Dlatego dobrym pomysłem jest ustawienie klucza jako categoryId, a później możemy go odzyskać.
Wartość grupy formularzy będzie wyglądać następująco:
Ale najczęściej chcemy uzyskać tylko listę categoryIds jako
["category2", "category3"]
. Muszę też napisać, żeby wziąć te dane. Takie podejście podoba mi się bardziej w porównaniu z formArray, ponieważ faktycznie mógłbym wziąć wartość z samego formularza.3. Własny walidator, aby zaznaczyć przynajmniej jedno pole wyboru
Zrobiłem walidator, aby sprawdzał co najmniej X checkbox jest zaznaczony, domyślnie będzie sprawdzał tylko z jednym checkboxem.
źródło
Po kliknięciu utwórz zdarzenie, a następnie ręcznie zmień wartość true na nazwę tego pola wyboru, a następnie nazwa lub true oceni to samo i możesz uzyskać wszystkie wartości zamiast listy prawda / fałsz. Dawny:
component.html
component.ts
Spowoduje to przechwycenie zdarzenia po tym, jak zostało już zmienione na true lub false przez Angular Forms, jeśli to prawda, zmieniam nazwę na nazwę tego, co reprezentuje pole wyboru, co w razie potrzeby zostanie również ocenione na true, jeśli jest sprawdzane pod kątem prawda / fałsz jako dobrze.
źródło
Jeśli chcesz użyć formularza reaktywnego Angular ( https://angular.io/guide/reactive-forms ).
Możesz użyć jednej kontrolki formularza, aby zarządzać wartością wyjściową grupy pól wyboru.
składnik
html
checklistState
Zarządza modelem / stanem danych wejściowych listy kontrolnej. Ten model umożliwia mapowanie bieżącego stanu do dowolnego formatu wartości, jakiego potrzebujesz.
Model:
checklist
Form ControlTa kontrolka przechowuje wartość, którą chciałbyś zapisać jako np
wartość wyjściowa:
"value_1,value_2"
Zobacz demo na https://stackblitz.com/edit/angular-multi-checklist
źródło
Moje rozwiązanie - rozwiązałem to dla Angular 5 z Material View
Połączenie odbywa się przez
W ten sposób może działać dla wielu tablic pól wyboru w jednym formularzu. Po prostu ustaw nazwę tablicy controls do połączenia za każdym razem.
Na koniec otrzymujesz formularz z tablicą oryginalnych identyfikatorów rekordów do zapisania / aktualizacji.
źródło
CZĘŚĆ WZORU: -
CZĘŚĆ KONTROLERA: -
źródło
Dodaj moje 5 centów) Model mojego pytania
template.html
component.ts
źródło
Powiązana odpowiedź dla @ nash11, oto jak utworzyć tablicę wartości pól wyboru
I
mają pole wyboru, które również zaznacza wszystkie pola wyboru:
https://stackblitz.com/edit/angular-checkbox-custom-value-with-selectall
źródło