Skip to content

Commit 15e0699

Browse files
committed
feat(popover-edit): Helper class to reduce form state preservation boilerplate
1 parent 778fc34 commit 15e0699

File tree

6 files changed

+55
-13
lines changed

6 files changed

+55
-13
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export interface Entry<FormValue> {
10+
value?: FormValue;
11+
}
12+
13+
/**
14+
* A convenience class for preserving unsaved form state while an edit lens is closed.
15+
*
16+
* Example usage:
17+
* class MyComponent {
18+
* readonly nameEditValues = new FormValueContainer&lt;Item, {name: string}&gt;();
19+
* }
20+
*
21+
* &lt;form cdkEditControl [(cdkEditControlPreservedFormValue)]="nameEditValues.for(item).value"&gt;
22+
*/
23+
export class FormValueContainer<Key extends object, FormValue> {
24+
private _formValues = new WeakMap<Key, Entry<FormValue>>();
25+
26+
for(key: Key): Entry<FormValue> {
27+
const _formValues = this._formValues;
28+
29+
let entry = _formValues.get(key);
30+
if (!entry) {
31+
// Expose entry as an object so that we can [(two-way)] bind to its value member
32+
entry = {};
33+
_formValues.set(key, entry);
34+
}
35+
36+
return entry;
37+
}
38+
}

src/cdk-experimental/popover-edit/popover-edit.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@ import {BidiModule, Direction} from '@angular/cdk/bidi';
1010
import {OverlayContainer} from '@angular/cdk/overlay';
1111
import {BehaviorSubject} from 'rxjs';
1212

13-
import {CdkPopoverEditColspan, CdkPopoverEditModule, PopoverEditClickOutBehavior} from './index';
13+
import {
14+
CdkPopoverEditColspan,
15+
CdkPopoverEditModule,
16+
FormValueContainer,
17+
PopoverEditClickOutBehavior,
18+
} from './index';
1419

1520
const NAME_EDIT_TEMPLATE = `
1621
<div style="background-color: white;">
1722
<form #f="ngForm"
1823
cdkEditControl
1924
(ngSubmit)="onSubmit(element, f)"
20-
[cdkEditControlPreservedFormValue]="preservedValues.get(element)"
21-
(cdkEditControlPreservedFormValueChange)="preservedValues.set(element, $event)"
25+
[(cdkEditControlPreservedFormValue)]="preservedValues.for(element).value"
2226
[cdkEditControlIgnoreSubmitUnlessValid]="ignoreSubmitUnlessValid"
2327
[cdkEditControlClickOutBehavior]="clickOutBehavior">
2428
<input [ngModel]="element.name" name="name" required>
@@ -58,7 +62,7 @@ interface PeriodicElement {
5862
abstract class BaseTestComponent {
5963
@ViewChild('table', {static: false}) table: ElementRef;
6064

61-
preservedValues = new Map<number, PeriodicElement>();
65+
preservedValues = new FormValueContainer<PeriodicElement, {'name': string}>();
6266

6367
ignoreSubmitUnlessValid = true;
6468
clickOutBehavior: PopoverEditClickOutBehavior = 'close';

src/cdk-experimental/popover-edit/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
export * from './edit-event-dispatcher';
1010
export * from './edit-ref';
1111
export * from './focus-dispatcher';
12+
export * from './form-value-container';
1213
export * from './lens-directives';
1314
export * from './popover-edit-module';
1415
export * from './popover-edit-position-strategy-factory';

src/material-examples/popover-edit-mat-table/popover-edit-mat-table-example.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
<form #f="ngForm"
99
matEditLens
1010
(ngSubmit)="onSubmitWeight(element, f)"
11-
[matEditLensPreservedFormValue]="preservedWeightValues.get(element)"
12-
(matEditLensPreservedFormValueChange)="preservedWeightValues.set(element, $event)">
11+
[(matEditLensPreservedFormValue)]="weightValues.for(element).value">
1312
<div mat-edit-content>
1413
<mat-form-field>
1514
<input matInput type="number" [ngModel]="element.weight" name="weight" required>
@@ -38,8 +37,7 @@
3837
<form #f="ngForm"
3938
matEditLens
4039
(ngSubmit)="onSubmitName(element, f)"
41-
[matEditLensPreservedFormValue]="preservedNameValues.get(element)"
42-
(matEditLensPreservedFormValueChange)="preservedNameValues.set(element, $event)">
40+
[(matEditLensPreservedFormValue)]="nameValues.for(element).value">
4341
<h2 mat-edit-title>Name</h2>
4442
<div mat-edit-content>
4543
<mat-form-field>

src/material-examples/popover-edit-mat-table/popover-edit-mat-table-example.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {Component} from '@angular/core';
22
import {DataSource} from '@angular/cdk/collections';
33
import {DomSanitizer} from '@angular/platform-browser';
4+
import {FormValueContainer} from '@angular/cdk-experimental/popover-edit';
45
import {NgForm} from '@angular/forms';
56
import {MatIconRegistry} from '@angular/material/icon';
67
import {BehaviorSubject, Observable} from 'rxjs';
@@ -47,8 +48,8 @@ export class PopoverEditMatTableExample {
4748
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
4849
dataSource = new ExampleDataSource();
4950

50-
readonly preservedNameValues = new WeakMap<PeriodicElement, any>();
51-
readonly preservedWeightValues = new WeakMap<PeriodicElement, any>();
51+
readonly nameValues = new FormValueContainer<PeriodicElement, any>();
52+
readonly weightValues = new FormValueContainer<PeriodicElement, any>();
5253

5354
constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
5455
iconRegistry.addSvgIcon(

src/material-experimental/popover-edit/popover-edit.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {BehaviorSubject} from 'rxjs';
1111

1212
import {
1313
CdkPopoverEditColspan,
14+
FormValueContainer,
1415
PopoverEditClickOutBehavior,
1516
} from '@angular/cdk-experimental/popover-edit';
1617
import {MatPopoverEditModule} from './index';
@@ -20,8 +21,7 @@ const NAME_EDIT_TEMPLATE = `
2021
<form #f="ngForm"
2122
matEditLens
2223
(ngSubmit)="onSubmit(element, f)"
23-
[matEditLensPreservedFormValue]="preservedValues.get(element)"
24-
(matEditLensPreservedFormValueChange)="preservedValues.set(element, $event)"
24+
[(matEditLensPreservedFormValue)]="preservedValues.for(element).value"
2525
[matEditLensIgnoreSubmitUnlessValid]="ignoreSubmitUnlessValid"
2626
[matEditLensClickOutBehavior]="clickOutBehavior">
2727
<input [ngModel]="element.name" name="name" required>
@@ -61,7 +61,7 @@ interface PeriodicElement {
6161
abstract class BaseTestComponent {
6262
@ViewChild('table', {static: false}) table: ElementRef;
6363

64-
preservedValues = new Map<number, PeriodicElement>();
64+
preservedValues = new FormValueContainer<PeriodicElement, {'name': string}>();
6565

6666
ignoreSubmitUnlessValid = true;
6767
clickOutBehavior: PopoverEditClickOutBehavior = 'close';

0 commit comments

Comments
 (0)