2017-08-13 19 views
23

Mam mały problem z moim formularzem.Angular4 - Brak akcesoriów do kontroli formularza

zrobiłem element niestandardowy:

<div formControlName="surveyType"> 
    <div *ngFor="let type of surveyTypes" 
     (click)="onSelectType(type)" 
     [class.selected]="type === selectedType"> 
    <md-icon>{{ type.icon }}</md-icon> 
    <span>{{ type.description }}</span> 
    </div> 
</div> 

próbuję dodać formControlName ale kanciasty nie chcę nic wiedzieć i po prostu mówiąc:

ERROR Error: No value accessor for form control with name: 'surveyType' 

Próbowałem dodać ngDefaultControl bez powodzenia. Wygląda na to, że nie ma wejścia/wybierz ... ale nie wiem, co robić.

Chciałbym przywiązać moje kliknięcie do tego formularzaControl, aby po kliknięciu na całą kartę, która wepchnęła mój "typ" do formControl. Czy to możliwe?

+0

mógłbyś wyjaśnić "wciskam 'typ' w formControl" części proszę? – Vega

+0

Nie wiem, moim celem jest: formControl iść do kontroli formularza w html, ale div nie jest formą kontroli. Chciałbym powiązać mój surveyType z type.id mojej karty div – jbtd

+0

Jeśli nie masz danych wejściowych, dlaczego potrzebujesz kontroli formularza i formularza? Czy nie potrzebujesz po prostu kliknąć karty i uzyskać informacje o karcie w kontrolerze? – Vega

Odpowiedz

35

formControlName można użyć jedynie na dyrektyw, które wdrażają ControlValueAccessor.

Wdrożenie interfejsu

Tak, aby robić to, co chcesz, musisz utworzyć komponent, który implementuje ControlValueAccessor, co oznacza realizację następujących trzech funkcji:

  • writeValue (mówi Kątowe, jak wpisać wartość z modelu do widoku)
  • registerOnChange (rejestruje funkcję modułu obsługi wywoływaną podczas zmiany widoku)
  • registerOnTouched (rejestruje program obsługi, który zostanie wywołany, gdy komponent otrzyma zdarzenie dotykowe, przydatne do sprawdzenia, czy komponent został skupiony).

Rejestracja dostawcy

Następnie, trzeba powiedzieć, że ta dyrektywa kątowa jest ControlValueAccessor (interfejs nie będzie go wyciąć, ponieważ jest usuwana z kodu gdy maszynopis jest kompilowany do kodu JavaScript). Zrobisz to przez rejestrując dostawcę.

Dostawca powinien dostarczyć NG_VALUE_ACCESSOR i use an existing value. Będziesz także potrzebować tutaj forwardRef. Zauważ, że NG_VALUE_ACCESSOR powinno być multi provider.

Na przykład, jeśli dyrektywa zwyczaj nazywa MyControlComponent, należy dodać coś wzdłuż następujące linie wewnątrz obiektu przekazany do @Component dekoratora:

providers: [ 
    { 
    provide: NG_VALUE_ACCESSOR, 
    multi: true, 
    useExisting: forwardRef(() => MyControlComponent), 
    } 
] 

Usage

komponent jest gotowy do użycia . Z template-driven forms, ngModel powiązanie będzie teraz działało poprawnie.

Dzięki reactive forms można teraz poprawnie używać formControlName, a formant formularza będzie działał zgodnie z oczekiwaniami.

Resources

+0

Nice! to powinno być w porządku z tym. Thx :) Spróbuję tego i będę na bieżąco informowany. – jbtd

+0

To zadziałało, ja robię komponent z kontrolerem wartości kontrolnej i teraz działa tak, jakbym chciał! Dzięki @Lazar Ljubenović – jbtd

+2

Wznowienie! Przydał mi się wiele razy, dzięki @Lazar: D –

6

myślę, że należy użyć formControlName="surveyType" na input a nie na div

+0

Tak, ale nie wiem jak zamienić moją kartę div w coś innego, co będzie formantem html – jbtd

+0

Punktem CustomValueAccessor jest dodanie kontroli formularza do WSZYSTKIEGO, nawet div – SoEzPz

+2

OMG Bro to był najbardziej przydatna odpowiedź. Dziękuję, nie zauważam tego. – George