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

Commit 50c9e5e

Browse files
TedSandermatanlurey
authored andcommitted
Create an AbstractControlGroup and AbstractForm which will allow different infrastructure to create different implementation of ControlGroups and Forms with different backing values.
Example usage: cl/205017920 Global Presubmit: https://test.corp.google.com/OCL:204254973:BASE:205149190:1531953387644:95fc22b0 PiperOrigin-RevId: 205178408
1 parent 77ef296 commit 50c9e5e

22 files changed

+120
-147
lines changed

angular_forms/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
### New Features
2+
3+
* Add AbstractControlGroup and AbstractNgForm to allow infrastructure to
4+
create their own form systems that can be backed by types such as a proto,
5+
or have different control group logic.
6+
17
### Breaking Changes
28

39
* Use value from AbstractControl for valueChanges event instead of internal

angular_forms/lib/angular_forms.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export 'src/directives.dart'
1717
setUpControlGroup,
1818
formDirectives,
1919
AbstractControlDirective,
20+
AbstractNgForm,
2021
ChangeFunction,
2122
CheckboxControlValueAccessor,
2223
ControlContainer,
@@ -48,7 +49,12 @@ export 'src/directives.dart'
4849
ValidatorFn;
4950
export 'src/form_builder.dart' show FormBuilder;
5051
export 'src/model.dart'
51-
show AbstractControl, Control, ControlGroup, ControlArray;
52+
show
53+
AbstractControl,
54+
Control,
55+
AbstractControlGroup,
56+
ControlGroup,
57+
ControlArray;
5258
export 'src/validators.dart' show NG_VALIDATORS, Validators;
5359

5460
/// Shorthand set of providers used for building Angular forms.

angular_forms/lib/src/directives.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export 'directives/ng_control_group.dart' show NgControlGroup;
3535
export 'directives/ng_control_name.dart' show NgControlName;
3636
// ignore: deprecated_member_use
3737
export 'directives/ng_control_status.dart' show NgControlStatus;
38-
export 'directives/ng_form.dart' show NgForm;
38+
export 'directives/ng_form.dart' show NgForm, AbstractNgForm;
3939
export 'directives/ng_form_control.dart' show NgFormControl;
4040
export 'directives/ng_form_model.dart' show NgFormModel;
4141
export 'directives/ng_model.dart' show NgModel;

angular_forms/lib/src/directives/abstract_form.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ import 'ng_control.dart' show NgControl;
1010
import 'ng_control_group.dart' show NgControlGroup;
1111

1212
/// A base implementation of [Form].
13-
abstract class AbstractForm extends ControlContainer implements Form {
14-
final _ngSubmit = new StreamController<ControlGroup>.broadcast(sync: true);
15-
final _ngBeforeSubmit =
16-
new StreamController<ControlGroup>.broadcast(sync: true);
13+
abstract class AbstractForm<T extends AbstractControlGroup>
14+
extends ControlContainer<T> implements Form {
15+
final _ngSubmit = new StreamController<T>.broadcast(sync: true);
16+
final _ngBeforeSubmit = new StreamController<T>.broadcast(sync: true);
1717

18-
ControlGroup get form;
18+
T get form;
1919

2020
/// An event fired with the user has triggered a form submission.
2121
@Output()
22-
Stream<ControlGroup> get ngSubmit => _ngSubmit.stream;
22+
Stream<T> get ngSubmit => _ngSubmit.stream;
2323

2424
/// An event that is fired before the main form submission event.
2525
///
2626
/// This is intended to be used to set form values or perform validation on
2727
/// submit instead of when a value changes.
2828
@Output()
29-
Stream<ControlGroup> get ngBeforeSubmit => _ngBeforeSubmit.stream;
29+
Stream<T> get ngBeforeSubmit => _ngBeforeSubmit.stream;
3030

3131
@HostListener('submit')
3232
void onSubmit(Event event) {
@@ -45,7 +45,7 @@ abstract class AbstractForm extends ControlContainer implements Form {
4545
Form get formDirective => this;
4646

4747
@override
48-
ControlGroup get control => form;
48+
T get control => form;
4949

5050
@override
5151
List<String> get path => [];
@@ -54,8 +54,8 @@ abstract class AbstractForm extends ControlContainer implements Form {
5454
Control getControl(NgControl dir) => form?.findPath(dir.path) as Control;
5555

5656
@override
57-
ControlGroup getControlGroup(NgControlGroup dir) =>
58-
(form?.findPath(dir.path) as ControlGroup);
57+
AbstractControlGroup getControlGroup(NgControlGroup dir) =>
58+
form?.findPath(dir.path) as AbstractControlGroup;
5959

6060
@override
6161
void updateModel(NgControl dir, dynamic value) {
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import '../model.dart' show ControlGroup;
1+
import '../model.dart' show AbstractControlGroup;
22
import 'abstract_control_directive.dart' show AbstractControlDirective;
33
import 'form_interface.dart' show Form;
44

55
/// A directive that contains multiple [NgControl]s contained in a
6-
/// [ControlGroup].
6+
/// [AbstractControlGroup].
77
///
88
/// Only used by the forms package.
9-
abstract class ControlContainer extends AbstractControlDirective<ControlGroup> {
9+
abstract class ControlContainer<T extends AbstractControlGroup>
10+
extends AbstractControlDirective<T> {
1011
/// Get the form to which this container belongs.
1112
Form get formDirective;
1213
}

angular_forms/lib/src/directives/form_interface.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import '../model.dart' show Control, ControlGroup;
1+
import '../model.dart' show Control, AbstractControlGroup;
22
import 'ng_control.dart' show NgControl;
33
import 'ng_control_group.dart' show NgControlGroup;
44

@@ -21,8 +21,9 @@ abstract class Form {
2121
/// Remove a group of controls from this form.
2222
void removeControlGroup(NgControlGroup dir);
2323

24-
/// Look up the [ControlGroup] associated with a particular [NgControlGroup].
25-
ControlGroup getControlGroup(NgControlGroup dir);
24+
/// Look up the [AbstractControlGroup] associated with a particular
25+
/// [NgControlGroup].
26+
AbstractControlGroup getControlGroup(NgControlGroup dir);
2627

2728
/// Update the model for a particular control with a new value.
2829
void updateModel(NgControl dir, dynamic value);

angular_forms/lib/src/directives/ng_control_group.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ import 'validators.dart' show ValidatorFn;
6060
],
6161
exportAs: 'ngForm',
6262
)
63-
class NgControlGroup extends ControlContainer implements OnInit, OnDestroy {
63+
class NgControlGroup extends ControlContainer<ControlGroup>
64+
implements OnInit, OnDestroy {
6465
final ValidatorFn validator;
6566
final ControlContainer _parent;
6667

angular_forms/lib/src/directives/ng_form.dart

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import 'dart:async';
33
import 'package:meta/meta.dart';
44
import 'package:angular/angular.dart';
55

6-
import '../model.dart' show AbstractControl, ControlGroup, Control;
6+
import '../model.dart'
7+
show AbstractControl, AbstractControlGroup, ControlGroup, Control;
78
import '../validators.dart' show NG_VALIDATORS;
89
import 'abstract_form.dart' show AbstractForm;
910
import 'control_container.dart' show ControlContainer;
@@ -75,24 +76,39 @@ import 'shared.dart' show setUpControl, setUpControlGroup, composeValidators;
7576
exportAs: 'ngForm',
7677
visibility: Visibility.all,
7778
)
78-
class NgForm extends AbstractForm {
79-
ControlGroup form;
80-
79+
class NgForm extends AbstractNgForm<ControlGroup> {
8180
NgForm(@Optional() @Self() @Inject(NG_VALIDATORS) List<dynamic> validators) {
8281
form = new ControlGroup({}, composeValidators(validators));
8382
}
8483

84+
@override
85+
ControlGroup createGroup(NgControlGroup _) => ControlGroup({});
86+
}
87+
88+
/// Abstract class to easily create forms that are template driven.
89+
///
90+
/// This allows an implementing form to easily specify how to create control
91+
/// groups, and controls. Allowing for infrastructure to create form systems
92+
/// that are backed by different types such as protos.
93+
abstract class AbstractNgForm<T extends AbstractControlGroup>
94+
extends AbstractForm<T> {
95+
T form;
96+
8597
@Input('ngDisabled')
8698
set disabled(bool isDisabled) {
8799
toggleDisabled(isDisabled);
88100
}
89101

90102
Map<String, AbstractControl> get controls => form.controls;
91103

104+
T createGroup(NgControlGroup dir);
105+
// This is separate to allow clients to override the logic if they wish.
106+
Control createControl(NgControl _) => Control();
107+
92108
@override
93109
void addControl(NgControl dir) {
94110
var container = findContainer(dir.path);
95-
var ctrl = new Control();
111+
var ctrl = createControl(dir);
96112
container.addControl(dir.name, ctrl);
97113
scheduleMicrotask(() {
98114
setUpControl(ctrl, dir);
@@ -114,7 +130,7 @@ class NgForm extends AbstractForm {
114130
@override
115131
void addControlGroup(NgControlGroup dir) {
116132
var container = findContainer(dir.path);
117-
var group = new ControlGroup({});
133+
var group = createGroup(dir);
118134
container.addControl(dir.name, group);
119135
scheduleMicrotask(() {
120136
setUpControlGroup(group, dir);
@@ -141,8 +157,8 @@ class NgForm extends AbstractForm {
141157
}
142158

143159
@protected
144-
ControlGroup findContainer(List<String> path) {
160+
T findContainer(List<String> path) {
145161
path.removeLast();
146-
return path.isEmpty ? form : (form.findPath(path) as ControlGroup);
162+
return path.isEmpty ? form : (form.findPath(path) as T);
147163
}
148164
}

angular_forms/lib/src/directives/ng_form_model.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ import 'validators.dart' show ValidatorFn;
8787
exportAs: 'ngForm',
8888
visibility: Visibility.all,
8989
)
90-
class NgFormModel extends AbstractForm implements AfterChanges {
90+
class NgFormModel extends AbstractForm<ControlGroup> implements AfterChanges {
9191
final ValidatorFn _validator;
9292

9393
bool _formChanged = false;

angular_forms/lib/src/directives/shared.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'dart:html';
22
import 'dart:js_util' as js_util;
33

4-
import '../model.dart' show Control, ControlGroup;
4+
import '../model.dart' show Control, AbstractControlGroup;
55
import '../validators.dart' show Validators;
66
import 'abstract_control_directive.dart' show AbstractControlDirective;
77
import 'checkbox_value_accessor.dart' show CheckboxControlValueAccessor;
@@ -43,7 +43,7 @@ void setUpControl(Control control, NgControl dir) {
4343
dir.valueAccessor.registerOnTouched(() => control.markAsTouched());
4444
}
4545

46-
void setUpControlGroup(ControlGroup control, NgControlGroup dir) {
46+
void setUpControlGroup(AbstractControlGroup control, NgControlGroup dir) {
4747
if (control == null) _throwError(dir, 'Cannot find control');
4848
control.validator = Validators.compose([control.validator, dir.validator]);
4949
}

0 commit comments

Comments
 (0)