feat(popover-edit): Helper class to reduce form state preservation boilerplate (#15939)

This commit is contained in:
Karl Seamon
2019-06-05 15:26:30 -04:00
committed by Joey Perrott
parent 8ecfc72269
commit 57b9902778
6 changed files with 50 additions and 12 deletions
@@ -0,0 +1,38 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export interface Entry<FormValue> {
value?: FormValue;
}
/**
* A convenience class for preserving unsaved form state while an edit lens is closed.
*
* Example usage:
* class MyComponent {
* readonly nameEditValues = new FormValueContainer&lt;Item, {name: string}&gt;();
* }
*
* &lt;form cdkEditControl [(cdkEditControlPreservedFormValue)]="nameEditValues.for(item).value"&gt;
*/
export class FormValueContainer<Key extends object, FormValue> {
private _formValues = new WeakMap<Key, Entry<FormValue>>();
for(key: Key): Entry<FormValue> {
const _formValues = this._formValues;
let entry = _formValues.get(key);
if (!entry) {
// Expose entry as an object so that we can [(two-way)] bind to its value member
entry = {};
_formValues.set(key, entry);
}
return entry;
}
}
@@ -14,6 +14,7 @@ import {
CdkPopoverEditColspan,
CdkPopoverEditModule,
HoverContentState,
FormValueContainer,
PopoverEditClickOutBehavior,
} from './index';
@@ -22,8 +23,7 @@ const NAME_EDIT_TEMPLATE = `
<form #f="ngForm"
cdkEditControl
(ngSubmit)="onSubmit(element, f)"
[cdkEditControlPreservedFormValue]="preservedValues.get(element)"
(cdkEditControlPreservedFormValueChange)="preservedValues.set(element, $event)"
[(cdkEditControlPreservedFormValue)]="preservedValues.for(element).value"
[cdkEditControlIgnoreSubmitUnlessValid]="ignoreSubmitUnlessValid"
[cdkEditControlClickOutBehavior]="clickOutBehavior">
<input [ngModel]="element.name" name="name" required>
@@ -63,7 +63,7 @@ interface PeriodicElement {
abstract class BaseTestComponent {
@ViewChild('table', {static: false}) table: ElementRef;
preservedValues = new Map<number, PeriodicElement>();
preservedValues = new FormValueContainer<PeriodicElement, {'name': string}>();
ignoreSubmitUnlessValid = true;
clickOutBehavior: PopoverEditClickOutBehavior = 'close';
@@ -9,6 +9,7 @@
export * from './edit-event-dispatcher';
export * from './edit-ref';
export * from './focus-dispatcher';
export * from './form-value-container';
export * from './lens-directives';
export * from './popover-edit-module';
export * from './popover-edit-position-strategy-factory';
@@ -8,8 +8,7 @@
<form #f="ngForm"
matEditLens
(ngSubmit)="onSubmitWeight(element, f)"
[matEditLensPreservedFormValue]="preservedWeightValues.get(element)"
(matEditLensPreservedFormValueChange)="preservedWeightValues.set(element, $event)">
[(matEditLensPreservedFormValue)]="weightValues.for(element).value">
<div mat-edit-content>
<mat-form-field>
<input matInput type="number" [ngModel]="element.weight" name="weight" required>
@@ -50,8 +49,7 @@
<form #f="ngForm"
matEditLens
(ngSubmit)="onSubmitName(element, f)"
[matEditLensPreservedFormValue]="preservedNameValues.get(element)"
(matEditLensPreservedFormValueChange)="preservedNameValues.set(element, $event)">
[(matEditLensPreservedFormValue)]="nameValues.for(element).value">
<h2 mat-edit-title>Name</h2>
<div mat-edit-content>
<mat-form-field>
@@ -1,5 +1,6 @@
import {Component} from '@angular/core';
import {DataSource} from '@angular/cdk/collections';
import {FormValueContainer} from '@angular/cdk-experimental/popover-edit';
import {NgForm} from '@angular/forms';
import {MatSnackBar} from '@angular/material/snack-bar';
import {BehaviorSubject, Observable} from 'rxjs';
@@ -46,8 +47,8 @@ export class PopoverEditMatTableExample {
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = new ExampleDataSource();
readonly preservedNameValues = new WeakMap<PeriodicElement, any>();
readonly preservedWeightValues = new WeakMap<PeriodicElement, any>();
readonly nameValues = new FormValueContainer<PeriodicElement, any>();
readonly weightValues = new FormValueContainer<PeriodicElement, any>();
constructor(private readonly _snackBar: MatSnackBar) {}
@@ -12,6 +12,7 @@ import {BehaviorSubject} from 'rxjs';
import {
CdkPopoverEditColspan,
HoverContentState,
FormValueContainer,
PopoverEditClickOutBehavior,
} from '@angular/cdk-experimental/popover-edit';
import {MatPopoverEditModule} from './index';
@@ -21,8 +22,7 @@ const NAME_EDIT_TEMPLATE = `
<form #f="ngForm"
matEditLens
(ngSubmit)="onSubmit(element, f)"
[matEditLensPreservedFormValue]="preservedValues.get(element)"
(matEditLensPreservedFormValueChange)="preservedValues.set(element, $event)"
[(matEditLensPreservedFormValue)]="preservedValues.for(element).value"
[matEditLensIgnoreSubmitUnlessValid]="ignoreSubmitUnlessValid"
[matEditLensClickOutBehavior]="clickOutBehavior">
<input [ngModel]="element.name" name="name" required>
@@ -62,7 +62,7 @@ interface PeriodicElement {
abstract class BaseTestComponent {
@ViewChild('table', {static: false}) table: ElementRef;
preservedValues = new Map<number, PeriodicElement>();
preservedValues = new FormValueContainer<PeriodicElement, {'name': string}>();
ignoreSubmitUnlessValid = true;
clickOutBehavior: PopoverEditClickOutBehavior = 'close';