Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

Commit

Permalink
Automated rollback of change.
Browse files Browse the repository at this point in the history
*** Reason for rollback ***

This cl is causing test breakages.

*** Original change description ***

feature(forms): Add initial support for disabled state to Control models.

A follow-up change will add support to the form directives.

Partial work towards #1037

***

PiperOrigin-RevId: 190869885
  • Loading branch information
TedSander authored and alorenzen committed Mar 29, 2018
1 parent 52527ce commit d4754b5
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 237 deletions.
3 changes: 0 additions & 3 deletions angular_forms/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
* Add `MemorizedForm` directive. This is a form that will not remove controls
if the control is taken out of the view, for example with a [NgIf].

* Add `disabled` state to `AbstractControl` models. Note: This is not yet
supported in the template-driven directives.

## Breaking Changes

* Remove `optionals` param from `ControlGroup` constructor. This will soon be
Expand Down
132 changes: 22 additions & 110 deletions angular_forms/lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ abstract class AbstractControl<T> {
/// occurring and errors are not yet available for the input value.
static const PENDING = 'PENDING';

/// Indicates that a FormControl is disabled, i.e. that the control is exempt
/// from ancestor calculations of validity or value.
static const DISABLED = 'DISABLED';

ValidatorFn validator;
T _value;
final _valueChanges = new StreamController<T>.broadcast();
Expand All @@ -58,10 +54,6 @@ abstract class AbstractControl<T> {

bool get valid => _status == VALID;

bool get disabled => _status == DISABLED;

bool get enabled => !disabled;

/// Returns the errors of this control.
Map<String, dynamic> get errors => _errors;

Expand Down Expand Up @@ -105,38 +97,6 @@ abstract class AbstractControl<T> {
}
}

void markAsDisabled({bool onlySelf, bool emitEvent}) {
onlySelf = onlySelf == true;
emitEvent = emitEvent ?? true;

_status = DISABLED;

_forEachChild(
(c) => c.markAsDisabled(onlySelf: onlySelf, emitEvent: emitEvent));
onUpdate();

if (emitEvent) _emitEvent();

_updateAncestors(onlySelf: onlySelf);
}

void markAsEnabled({bool onlySelf, bool emitEvent}) {
onlySelf = onlySelf == true;
emitEvent = emitEvent ?? true;
_status = VALID;
_forEachChild(
(c) => c.markAsEnabled(onlySelf: onlySelf, emitEvent: emitEvent));
updateValueAndValidity(onlySelf: true, emitEvent: emitEvent);
_updateAncestors(onlySelf: onlySelf);
}

void _updateAncestors({bool onlySelf}) {
if (_parent != null && !onlySelf) {
_parent.updateValueAndValidity();
// TODO(alorenzen): Update parent pristine and touched.
}
}

void setParent(AbstractControl parent) {
_parent = parent;
}
Expand All @@ -147,17 +107,15 @@ abstract class AbstractControl<T> {
onUpdate();
_errors = _runValidator();
_status = _calculateStatus();
if (emitEvent) _emitEvent();
if (emitEvent) {
_valueChanges.add(_value);
_statusChanges.add(_status);
}
if (_parent != null && !onlySelf) {
_parent.updateValueAndValidity(onlySelf: onlySelf, emitEvent: emitEvent);
}
}

void _emitEvent() {
_valueChanges.add(_value);
_statusChanges.add(_status);
}

Map<String, dynamic> _runValidator() =>
validator != null ? validator(this) : null;

Expand Down Expand Up @@ -242,7 +200,6 @@ abstract class AbstractControl<T> {
if (_errors != null) return INVALID;
if (_anyControlsHaveStatus(PENDING)) return PENDING;
if (_anyControlsHaveStatus(INVALID)) return INVALID;
if (_allControlsHaveStatus(DISABLED)) return DISABLED;
return VALID;
}

Expand All @@ -254,9 +211,6 @@ abstract class AbstractControl<T> {
void onUpdate();

bool _anyControlsHaveStatus(String status);
bool _allControlsHaveStatus(String status);

void _forEachChild(void callback(AbstractControl c));
}

/// Defines a part of a form that cannot be divided into other controls.
Expand Down Expand Up @@ -315,12 +269,6 @@ class Control<T> extends AbstractControl<T> {
@override
bool _anyControlsHaveStatus(String status) => false;

@override
bool _allControlsHaveStatus(String status) => this.status == status;

@override
void _forEachChild(void callback(AbstractControl c)) {}

/// Register a listener for change events.
///
/// Used internally to connect the model with the [ValueAccessor] which will
Expand All @@ -344,6 +292,7 @@ class Control<T> extends AbstractControl<T> {
/// [ControlArray] can also contain other controls, but is of variable length.
class ControlGroup extends AbstractControl<Map<String, dynamic>> {
final Map<String, AbstractControl> controls;
final Map<String, bool> _optionals = {};

ControlGroup(this.controls, [ValidatorFn validator]) : super(validator) {
_setParentForControls(this, controls.values);
Expand All @@ -362,16 +311,19 @@ class ControlGroup extends AbstractControl<Map<String, dynamic>> {

/// Mark the named control as non-optional.
void include(String controlName) {
controls[controlName]?.markAsEnabled();
_optionals[controlName] = true;
updateValueAndValidity();
}

/// Mark the named control as optional.
void exclude(String controlName) {
controls[controlName]?.markAsDisabled();
_optionals[controlName] = false;
updateValueAndValidity();
}

/// Check whether there is a control with the given name in the group.
bool contains(String controlName) => controls.containsKey(controlName);
bool contains(String controlName) =>
controls.containsKey(controlName) && _included(controlName);

@override
void onUpdate() {
Expand All @@ -380,38 +332,22 @@ class ControlGroup extends AbstractControl<Map<String, dynamic>> {

@override
bool _anyControlsHaveStatus(String status) {
for (var name in controls.keys) {
if (contains(name) && controls[name].status == status) return true;
}
return false;
}

@override
bool _allControlsHaveStatus(String status) {
for (var name in controls.keys) {
if (!contains(name) || controls[name].status != status) return false;
}
return true;
}

@override
void _forEachChild(void callback(AbstractControl c)) {
for (var control in controls.values) {
callback(control);
}
return controls.keys.any((name) {
return contains(name) && controls[name].status == status;
});
}

Map<String, dynamic> _reduceValue() {
final res = <String, dynamic>{};
for (var name in controls.keys) {
if (_included(name) || disabled) {
res[name] = controls[name].value;
controls.forEach((name, control) {
if (_included(name)) {
res[name] = control.value;
}
}
});
return res;
}

bool _included(String controlName) => controls[controlName]?.enabled ?? false;
bool _included(String controlName) => _optionals[controlName] != false;
}

/// Defines a part of a form, of variable length, that can contain other
Expand Down Expand Up @@ -469,36 +405,12 @@ class ControlArray extends AbstractControl<List> {

@override
void onUpdate() {
_value = [];
for (var control in controls) {
if (control.enabled || disabled) {
_value.add(control.value);
}
}
}

@override
bool _anyControlsHaveStatus(String status) {
for (var control in controls) {
if (control.status == status) return true;
}
return false;
_value = controls.map((control) => control.value).toList();
}

@override
bool _allControlsHaveStatus(String status) {
for (var control in controls) {
if (control.status != status) return false;
}
return true;
}

@override
void _forEachChild(void callback(AbstractControl c)) {
for (var control in controls) {
callback(control);
}
}
bool _anyControlsHaveStatus(String status) =>
controls.any((c) => c.status == status);
}

void _setParentForControls(
Expand Down
124 changes: 0 additions & 124 deletions angular_forms/test/model_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -170,41 +170,6 @@ void main() {
expect(g.errors, isNull);
});
});
group('disabled', () {
Control control;
ControlGroup group;

setUp(() {
control = new Control('some value');
group = new ControlGroup({'one': control});
});

test('should update status', () {
expect(control.disabled, false);
control.markAsDisabled();
expect(control.disabled, true);
control.markAsEnabled();
expect(control.disabled, false);
});

test('should programatically change value, but not status', () {
expect(control.value, 'some value');
control.markAsDisabled();
expect(control.value, 'some value');
control.updateValue('new value');
expect(control.value, 'new value',
reason: 'Value changes are propagated when disabled.');
expect(control.disabled, true);
});

test('should update parent', () {
expect(group.disabled, false);
control.markAsDisabled();
expect(group.disabled, true);
control.markAsEnabled();
expect(group.disabled, false);
});
});
});

group('ControlGroup', () {
Expand Down Expand Up @@ -334,51 +299,6 @@ void main() {
expect(g.getError('required', ['invalid']), null);
});
});

group('disabled', () {
Control control;
ControlGroup group;

setUp(() {
control = new Control('some value');
group = new ControlGroup(
{'one': control, 'two': new Control('other value')});
});

test('should update status', () {
expect(group.disabled, false);
group.markAsDisabled();
expect(group.disabled, true);
group.markAsEnabled();
expect(group.disabled, false);
});

test('should ignore values from disabled children', () {
expect(group.value, {'one': 'some value', 'two': 'other value'});
control.markAsDisabled();
expect(group.value, {'two': 'other value'});
});

test('should ignore changes in child values', () {
expect(group.value, {'one': 'some value', 'two': 'other value'});
group.markAsDisabled();
expect(group.value, {'one': 'some value', 'two': 'other value'});
control.updateValue('new value');
expect(group.disabled, true);
expect(group.value, {'one': 'new value', 'two': 'other value'},
reason: 'Value changes are propagated when disabled.');
group.markAsEnabled();
expect(group.value, {'one': 'new value', 'two': 'other value'});
});

test('should update children', () {
expect(control.disabled, false);
group.markAsDisabled();
expect(control.disabled, true);
group.markAsEnabled();
expect(control.disabled, false);
});
});
});

group('ControlArray', () {
Expand Down Expand Up @@ -542,50 +462,6 @@ void main() {
expect(g.findPath(['array', '0']).value, '111');
});
});

group('disabled', () {
Control control;
ControlArray array;

setUp(() {
control = new Control('some value');
array = new ControlArray([control, new Control('other value')]);
});

test('should update status', () {
expect(array.disabled, false);
array.markAsDisabled();
expect(array.disabled, true);
array.markAsEnabled();
expect(array.disabled, false);
});

test('should ignore values from disabled children', () {
expect(array.value, ['some value', 'other value']);
control.markAsDisabled();
expect(array.value, ['other value']);
});

test('should ignore changes in child values', () {
expect(array.value, ['some value', 'other value']);
array.markAsDisabled();
expect(array.value, ['some value', 'other value']);
control.updateValue('new value');
expect(array.disabled, true);
expect(array.value, ['new value', 'other value'],
reason: 'Value changes are propagated when disabled.');
array.markAsEnabled();
expect(array.value, ['new value', 'other value']);
});

test('should update children', () {
expect(control.disabled, false);
array.markAsDisabled();
expect(control.disabled, true);
array.markAsEnabled();
expect(control.disabled, false);
});
});
});
});
}

0 comments on commit d4754b5

Please sign in to comment.