Skip to content

Commit d29a9a9

Browse files
m18vsavkin
authored andcommitted
fix(forms): handle control change in NgFormControl
when a new Control instance is bound to the directive, use the new instance, not the old one
1 parent 485c85b commit d29a9a9

3 files changed

Lines changed: 28 additions & 15 deletions

File tree

modules/angular2/src/core/forms/directives/ng_form_control.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {NgControl} from './ng_control';
88
import {Control} from '../model';
99
import {Validators, NG_VALIDATORS} from '../validators';
1010
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
11-
import {setUpControl, isPropertyUpdated, selectValueAccessor} from './shared';
11+
import {setUpControl, isPropertyUpdated, isControlChanged, selectValueAccessor} from './shared';
1212

1313
const formControlBinding =
1414
CONST_EXPR(new Provider(NgControl, {useExisting: forwardRef(() => NgFormControl)}));
@@ -70,8 +70,6 @@ const formControlBinding =
7070
export class NgFormControl extends NgControl implements OnChanges {
7171
form: Control;
7272
update = new EventEmitter();
73-
/** @internal */
74-
_added = false;
7573
model: any;
7674
viewModel: any;
7775
validators: Function[];
@@ -84,10 +82,9 @@ export class NgFormControl extends NgControl implements OnChanges {
8482
}
8583

8684
onChanges(changes: {[key: string]: SimpleChange}): void {
87-
if (!this._added) {
85+
if (isControlChanged(changes)) {
8886
setUpControl(this.form, this);
8987
this.form.updateValidity();
90-
this._added = true;
9188
}
9289
if (isPropertyUpdated(changes, this.viewModel)) {
9390
this.form.updateValue(this.model);

modules/angular2/src/core/forms/directives/shared.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any)
6060
return !looseIdentical(viewModel, change.currentValue);
6161
}
6262

63+
export function isControlChanged(changes: {[key: string]: any}): boolean {
64+
if (!StringMapWrapper.contains(changes, "form")) return false;
65+
var change = changes["form"];
66+
return change.previousValue !== change.currentValue;
67+
}
68+
6369
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
6470
export function selectValueAccessor(dir: NgControl, valueAccessors: ControlValueAccessor[]):
6571
ControlValueAccessor {

modules/angular2/test/core/forms/directives_spec.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838

3939
import {selectValueAccessor} from 'angular2/src/core/forms/directives/shared';
4040

41+
import {SimpleChange} from 'angular2/src/core/change_detection';
4142

4243
class DummyControlValueAccessor implements ControlValueAccessor {
4344
writtenValue;
@@ -275,6 +276,16 @@ export function main() {
275276
describe("NgFormControl", () => {
276277
var controlDir;
277278
var control;
279+
var checkProperties = function(control) {
280+
expect(controlDir.control).toBe(control);
281+
expect(controlDir.value).toBe(control.value);
282+
expect(controlDir.valid).toBe(control.valid);
283+
expect(controlDir.errors).toBe(control.errors);
284+
expect(controlDir.pristine).toBe(control.pristine);
285+
expect(controlDir.dirty).toBe(control.dirty);
286+
expect(controlDir.touched).toBe(control.touched);
287+
expect(controlDir.untouched).toBe(control.untouched);
288+
};
278289

279290
beforeEach(() => {
280291
controlDir = new NgFormControl([], [defaultAccessor]);
@@ -284,15 +295,14 @@ export function main() {
284295
controlDir.form = control;
285296
});
286297

287-
it("should reexport control properties", () => {
288-
expect(controlDir.control).toBe(control);
289-
expect(controlDir.value).toBe(control.value);
290-
expect(controlDir.valid).toBe(control.valid);
291-
expect(controlDir.errors).toBe(control.errors);
292-
expect(controlDir.pristine).toBe(control.pristine);
293-
expect(controlDir.dirty).toBe(control.dirty);
294-
expect(controlDir.touched).toBe(control.touched);
295-
expect(controlDir.untouched).toBe(control.untouched);
298+
it("should reexport control properties", () => { checkProperties(control); });
299+
300+
it("should reexport new control properties", () => {
301+
var newControl = new Control(null);
302+
controlDir.form = newControl;
303+
controlDir.onChanges({"form": new SimpleChange(control, newControl)});
304+
305+
checkProperties(newControl);
296306
});
297307

298308
it("should set up validator", () => {
@@ -301,7 +311,7 @@ export function main() {
301311
expect(control.valid).toBe(true);
302312

303313
// this will add the required validator and recalculate the validity
304-
controlDir.onChanges({});
314+
controlDir.onChanges({"form": new SimpleChange(null, control)});
305315

306316
expect(control.valid).toBe(false);
307317
});

0 commit comments

Comments
 (0)