@@ -305,6 +305,84 @@ describe('ngModel', function() {
305
305
expect ( element ) . toBeInvalid ( ) ;
306
306
expect ( element ) . toHaveClass ( 'ng-invalid-required' ) ;
307
307
} ) ) ;
308
+
309
+
310
+ it ( 'should register/deregister a nested ngModel with parent form when entering or leaving DOM' ,
311
+ inject ( function ( $compile , $rootScope ) {
312
+
313
+ var element = $compile ( '<form name="myForm">' +
314
+ '<input ng-if="inputPresent" name="myControl" ng-model="value" required >' +
315
+ '</form>' ) ( $rootScope ) ;
316
+ var isFormValid ;
317
+
318
+ $rootScope . inputPresent = false ;
319
+ $rootScope . $watch ( 'myForm.$valid' , function ( value ) { isFormValid = value ; } ) ;
320
+
321
+ $rootScope . $apply ( ) ;
322
+
323
+ expect ( $rootScope . myForm . $valid ) . toBe ( true ) ;
324
+ expect ( isFormValid ) . toBe ( true ) ;
325
+ expect ( $rootScope . myForm . myControl ) . toBeUndefined ( ) ;
326
+
327
+ $rootScope . inputPresent = true ;
328
+ $rootScope . $apply ( ) ;
329
+
330
+ expect ( $rootScope . myForm . $valid ) . toBe ( false ) ;
331
+ expect ( isFormValid ) . toBe ( false ) ;
332
+ expect ( $rootScope . myForm . myControl ) . toBeDefined ( ) ;
333
+
334
+ $rootScope . inputPresent = false ;
335
+ $rootScope . $apply ( ) ;
336
+
337
+ expect ( $rootScope . myForm . $valid ) . toBe ( true ) ;
338
+ expect ( isFormValid ) . toBe ( true ) ;
339
+ expect ( $rootScope . myForm . myControl ) . toBeUndefined ( ) ;
340
+
341
+ dealoc ( element ) ;
342
+ } ) ) ;
343
+
344
+
345
+ it ( 'should register/deregister a nested ngModel with parent form when entering or leaving DOM with animations' ,
346
+ function ( ) {
347
+
348
+ // ngAnimate performs the dom manipulation after digest, and since the form validity can be affected by a form
349
+ // control going away we must ensure that the deregistration happens during the digest while we are still doing
350
+ // dirty checking.
351
+ module ( 'ngAnimate' ) ;
352
+
353
+ inject ( function ( $compile , $rootScope ) {
354
+ var element = $compile ( '<form name="myForm">' +
355
+ '<input ng-if="inputPresent" name="myControl" ng-model="value" required >' +
356
+ '</form>' ) ( $rootScope ) ;
357
+ var isFormValid ;
358
+
359
+ $rootScope . inputPresent = false ;
360
+ // this watch ensure that the form validity gets updated during digest (so that we can observe it)
361
+ $rootScope . $watch ( 'myForm.$valid' , function ( value ) { isFormValid = value ; } ) ;
362
+
363
+ $rootScope . $apply ( ) ;
364
+
365
+ expect ( $rootScope . myForm . $valid ) . toBe ( true ) ;
366
+ expect ( isFormValid ) . toBe ( true ) ;
367
+ expect ( $rootScope . myForm . myControl ) . toBeUndefined ( ) ;
368
+
369
+ $rootScope . inputPresent = true ;
370
+ $rootScope . $apply ( ) ;
371
+
372
+ expect ( $rootScope . myForm . $valid ) . toBe ( false ) ;
373
+ expect ( isFormValid ) . toBe ( false ) ;
374
+ expect ( $rootScope . myForm . myControl ) . toBeDefined ( ) ;
375
+
376
+ $rootScope . inputPresent = false ;
377
+ $rootScope . $apply ( ) ;
378
+
379
+ expect ( $rootScope . myForm . $valid ) . toBe ( true ) ;
380
+ expect ( isFormValid ) . toBe ( true ) ;
381
+ expect ( $rootScope . myForm . myControl ) . toBeUndefined ( ) ;
382
+
383
+ dealoc ( element ) ;
384
+ } ) ;
385
+ } ) ;
308
386
} ) ;
309
387
310
388
@@ -369,17 +447,6 @@ describe('input', function() {
369
447
} ) ;
370
448
371
449
372
- it ( 'should cleanup it self from the parent form' , function ( ) {
373
- compileInput ( '<input ng-model="name" name="alias" required>' ) ;
374
-
375
- scope . $apply ( ) ;
376
- expect ( scope . form . $error . required . length ) . toBe ( 1 ) ;
377
-
378
- inputElm . remove ( ) ;
379
- expect ( scope . form . $error . required ) . toBe ( false ) ;
380
- } ) ;
381
-
382
-
383
450
it ( 'should update the model on "blur" event' , function ( ) {
384
451
compileInput ( '<input type="text" ng-model="name" name="alias" ng-change="change()" />' ) ;
385
452
0 commit comments