File tree Expand file tree Collapse file tree 2 files changed +45
-2
lines changed Expand file tree Collapse file tree 2 files changed +45
-2
lines changed Original file line number Diff line number Diff line change 7
7
*/
8
8
9
9
import {
10
+ afterNextRender ,
10
11
computed ,
11
12
DestroyRef ,
12
13
Directive ,
@@ -177,9 +178,11 @@ export class Control<T> {
177
178
input : HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement ,
178
179
) : void {
179
180
const inputType =
180
- input instanceof HTMLTextAreaElement || input instanceof HTMLSelectElement
181
+ input instanceof HTMLTextAreaElement
181
182
? 'text'
182
- : input . type ;
183
+ : input instanceof HTMLSelectElement
184
+ ? 'select'
185
+ : input . type ;
183
186
184
187
input . addEventListener ( 'input' , ( ) => {
185
188
switch ( inputType ) {
@@ -227,6 +230,15 @@ export class Control<T> {
227
230
} ,
228
231
) ;
229
232
break ;
233
+ case 'select' :
234
+ this . maybeSynchronize (
235
+ ( ) => this . state ( ) . value ( ) ,
236
+ ( value ) => {
237
+ // A select will not take a value unil the value's option has rendered.
238
+ afterNextRender ( ( ) => ( input . value = value as string ) , { injector : this . injector } ) ;
239
+ } ,
240
+ ) ;
241
+ break ;
230
242
default :
231
243
this . maybeSynchronize (
232
244
( ) => this . state ( ) . value ( ) ,
Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ import {
22
22
Control ,
23
23
disabled ,
24
24
form ,
25
+ hidden ,
25
26
max ,
26
27
MAX ,
27
28
maxLength ,
@@ -196,6 +197,36 @@ describe('control directive', () => {
196
197
expect ( cmp . f ( ) . value ( ) ) . toBe ( 'two' ) ;
197
198
} ) ;
198
199
200
+ it ( 'should assign correct value when unhiding select' , async ( ) => {
201
+ @Component ( {
202
+ imports : [ Control ] ,
203
+ template : `
204
+ @if (!f().hidden()) {
205
+ <select #select [control]="f">
206
+ @for(opt of options; track opt) {
207
+ <option [value]="opt">{{opt}}</option>
208
+ }
209
+ </select>
210
+ }
211
+ ` ,
212
+ } )
213
+ class TestCmp {
214
+ f = form ( signal ( '' ) , ( p ) => hidden ( p , ( { value} ) => value ( ) === '' ) ) ;
215
+ select = viewChild < ElementRef < HTMLSelectElement > > ( 'select' ) ;
216
+ options = [ 'one' , 'two' , 'three' ] ;
217
+ }
218
+
219
+ const fix = act ( ( ) => TestBed . createComponent ( TestCmp ) ) ;
220
+ const cmp = fix . componentInstance as TestCmp ;
221
+
222
+ expect ( fix . componentInstance . select ( ) ) . toBeUndefined ( ) ;
223
+
224
+ cmp . f ( ) . value . set ( 'two' ) ;
225
+ await fix . whenStable ( ) ;
226
+ expect ( fix . componentInstance . select ( ) ) . not . toBeUndefined ( ) ;
227
+ expect ( fix . componentInstance . select ( ) ! . nativeElement . value ) . toEqual ( 'two' ) ;
228
+ } ) ;
229
+
199
230
it ( 'synchronizes with a custom value control' , ( ) => {
200
231
@Component ( {
201
232
selector : 'my-input' ,
You can’t perform that action at this time.
0 commit comments