Radio buttons in Angular2 Model Driven forms not w

2019-09-11 04:24发布

问题:

If I create radio buttons in my model driven form, they work fine but they don't have the radio button selected reflected by the formControlName default value. For example:

<input type="radio" formControlName="isPublic" name="isPublic" value="false" id="keepPrivate" ><label for="keepPrivate">Keep it Private</label>
<input type="radio" formControlName="isPublic" name="isPublic" value="true" id="makePublic" ><label for="makePublic">Make it Public</label>
{{form.value.isPublic}}

If I have this it works correctly, but I can see the value of form.value.isPublic is false (as output in the last line to confirm) and yet no radio button is selected by default.

I tried to correct this by adding [checked] to each to drive the default value. This works for the page load, in that defaults are properly selected in the radio buttons. It even works for ONE selection - in that I can select the other radio button, it will be selected, the first one will be unselected, and the {{form.value.isPublic}} will change from false to true.

<input type="radio" formControlName="isPublic" [checked]="!form.value.isPublic" name="isPublic" value="false" id="keepPrivate" ><label for="keepPrivate">Keep it Private</label>
<input type="radio" formControlName="isPublic" [checked]="form.value.isPublic" name="isPublic" value="true" id="makePublic" ><label for="makePublic">Make it Public</label>
{{form.value.isPublic}}

The problem comes when I select the first radio button again - on the first click the radio button selection state doesn't change at all, but the {{form.value.isPublic}} output changes back to false. If I click it again, then the radio button selection state changes. So it takes two clicks to switch it back to the default. If I click the other one again after that, it changes as expected but switching back to the first one takes two clicks (one click updates the form value and the second click changes the selection state of the radio button).

What should I be doing in this situation to have the radio buttons function correctly and reflect the default value for the form?

回答1:

After experimenting with using values from the form object to drive other Angular2 directives (like *ngIf) I discovered that the behaviour is always a little strange. For example, if I draw parts of the page using *ngIf based on the value of form.value.isProfilePublic, the *ngIf section would only change once even though I can see the value of that variable is changing. It isn't important to the answer so I won't elaborate but bottom line is that using form values to dynamically drive things that can update the form value itself doesn't work as I'd expect (likely for a good reason).

...so now I'm using a different variable not related to the form to drive the default selection and it works fine. So, the following works:

<input type="radio" formControlName="isProfilePublic" name="isProfilePublic" [checked]="!currentUser.isProfilePublic" value="false" id="keepPrivate" ><label for="keepPrivate">Keep it Private</label>
<input type="radio" formControlName="isProfilePublic" name="isProfilePublic" [checked]="currentUser.isProfilePublic" value="true" id="makePublic" ><label for="makePublic">Make it Public</label>


回答2:

I can't explain needing two clicks, but this should work:

<label>
    <input type="radio" formControlName="isPublic" value="true" id="isPublic" (change)="form.value.isPublic = true"/> Make it public
</label>
<label>
    <input type="radio" formControlName="isPublic" value="false" id="isPublic" (change)="form.value.isPublic = false"/> Keep it private
</label>

On my project we are generating the radio buttons dynamically based on the 'questions' example in the docs for Angular 2 Dynamic Forms

<label class="radio-inline" *ngFor="let opt of input.options">
    <input type="radio" [formControlName]="input.key" [value]="opt.value" [id]="input.key" (change)="input.value = opt.value">
    {{opt.label}}
</label>