Skip to content

Commit 3bc6020

Browse files
kseamonjosephperrott
authored andcommitted
feat(popover-edit): Helper class to reduce form state preservation boilerplate (#15939)
1 parent 0871d88 commit 3bc6020

File tree

6 files changed

+50
-12
lines changed

6 files changed

+50
-12
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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
CdkPopoverEditColspan,
1515
CdkPopoverEditModule,
1616
HoverContentState,
17+
FormValueContainer,
1718
PopoverEditClickOutBehavior,
1819
} from './index';
1920

@@ -22,8 +23,7 @@ const NAME_EDIT_TEMPLATE = `
2223
<form #f="ngForm"
2324
cdkEditControl
2425
(ngSubmit)="onSubmit(element, f)"
25-
[cdkEditControlPreservedFormValue]="preservedValues.get(element)"
26-
(cdkEditControlPreservedFormValueChange)="preservedValues.set(element, $event)"
26+
[(cdkEditControlPreservedFormValue)]="preservedValues.for(element).value"
2727
[cdkEditControlIgnoreSubmitUnlessValid]="ignoreSubmitUnlessValid"
2828
[cdkEditControlClickOutBehavior]="clickOutBehavior">
2929
<input [ngModel]="element.name" name="name" required>
@@ -63,7 +63,7 @@ interface PeriodicElement {
6363
abstract class BaseTestComponent {
6464
@ViewChild('table', {static: false}) table: ElementRef;
6565

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

6868
ignoreSubmitUnlessValid = true;
6969
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>
@@ -50,8 +49,7 @@
5049
<form #f="ngForm"
5150
matEditLens
5251
(ngSubmit)="onSubmitName(element, f)"
53-
[matEditLensPreservedFormValue]="preservedNameValues.get(element)"
54-
(matEditLensPreservedFormValueChange)="preservedNameValues.set(element, $event)">
52+
[(matEditLensPreservedFormValue)]="nameValues.for(element).value">
5553
<h2 mat-edit-title>Name</h2>
5654
<div mat-edit-content>
5755
<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,5 +1,6 @@
11
import {Component} from '@angular/core';
22
import {DataSource} from '@angular/cdk/collections';
3+
import {FormValueContainer} from '@angular/cdk-experimental/popover-edit';
34
import {NgForm} from '@angular/forms';
45
import {MatSnackBar} from '@angular/material/snack-bar';
56
import {BehaviorSubject, Observable} from 'rxjs';
@@ -46,8 +47,8 @@ export class PopoverEditMatTableExample {
4647
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
4748
dataSource = new ExampleDataSource();
4849

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

5253
constructor(private readonly _snackBar: MatSnackBar) {}
5354

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {BehaviorSubject} from 'rxjs';
1212
import {
1313
CdkPopoverEditColspan,
1414
HoverContentState,
15+
FormValueContainer,
1516
PopoverEditClickOutBehavior,
1617
} from '@angular/cdk-experimental/popover-edit';
1718
import {MatPopoverEditModule} from './index';
@@ -21,8 +22,7 @@ const NAME_EDIT_TEMPLATE = `
2122
<form #f="ngForm"
2223
matEditLens
2324
(ngSubmit)="onSubmit(element, f)"
24-
[matEditLensPreservedFormValue]="preservedValues.get(element)"
25-
(matEditLensPreservedFormValueChange)="preservedValues.set(element, $event)"
25+
[(matEditLensPreservedFormValue)]="preservedValues.for(element).value"
2626
[matEditLensIgnoreSubmitUnlessValid]="ignoreSubmitUnlessValid"
2727
[matEditLensClickOutBehavior]="clickOutBehavior">
2828
<input [ngModel]="element.name" name="name" required>
@@ -62,7 +62,7 @@ interface PeriodicElement {
6262
abstract class BaseTestComponent {
6363
@ViewChild('table', {static: false}) table: ElementRef;
6464

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

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

0 commit comments

Comments
 (0)