Angular中Mat-Dialog临时数据存储方案咨询(替代内存存储)
Angular FormArray 临时数据存储方案(除内存外)
问题背景
我正在开发一个Angular对话框组件,用于填充FormArray——根据用户指定的qtyReceived值生成对应行数的序列号输入框。现在需要解决的是:如何临时保存用户已填写的数据?除了内存存储外,还有哪些可行的替代方案?
现有代码实现
组件初始化逻辑
ngOnInit(): void { this.serialForm = this.fb.group({ id: [0], deliveryReceiptDetailsId:[0], itemCode:['', Validators.required], qtyReceived:[0, Validators.required], inputs: this.fb.array([this.CreateArray()]), }); this.serialForm.get('qtyReceived').valueChanges.subscribe((res) => { for (let i = this.displayArray.length; i < res; i++) { this.displayArray.push(this.CreateArray()); console.log(this.displayArray); } }); this.serialForm.get('id').setValue(this.data.id), this.serialForm.get('qtyReceived').setValue(this.data.qtyReceived), this.serialForm.get('itemCode').setValue(this.data.propertyNo) } get displayArray():FormArray{ return this.serialForm.get('inputs') as FormArray; } CreateArray():FormGroup{ return new FormGroup({ serialNum: new FormControl('', {validators: [Validators.required]}), }); }
内存存储服务
@Injectable({ providedIn: 'root' }) export class SerialCodeService { private url = 'api/serial'; private headers = new HttpHeaders({ 'Content-Type': 'application/json' }); constructor(private http: HttpClient) { } getHeroes (data:any): Observable<any> { return this.http.post(this.url, data); } }
InMemoryDataService 示例数据
@Injectable({ providedIn: 'root' }) export class InMemoryDataService implements InMemoryDbService { createDb() { const serial = [ {id: 1, deliveryReceiptDetailsId: 0, itemCode:'sample1', qtyReceived:0 ,serialNum:"" }, {id: 2, deliveryReceiptDetailsId: 0, itemCode:'sample2', qtyReceived:0 ,serialNum:"" }, {id: 3, deliveryReceiptDetailsId: 0, itemCode:'sample3', qtyReceived:0 ,serialNum:""}, ]; return {serial}; } genId(SerialBarCode: SerialCodeDTO[]): number{ return SerialBarCode.length > 0 ? Math.max(...SerialBarCode.map(serial => serial.id)) + 1 : 1; } }
替代存储方案
1. 浏览器本地存储(LocalStorage/SessionStorage)
这是前端最常用的临时存储方案,实现简单:
- LocalStorage:数据持久化存储,除非用户手动清除或代码删除;
- SessionStorage:数据仅在当前浏览器会话有效,关闭标签页后自动清空。
实现思路:监听表单值变化,将Form的value序列化为JSON字符串存入存储;组件初始化时读取并恢复表单状态。
修改组件代码示例:
ngOnInit(): void { // 初始化表单 this.serialForm = this.fb.group({ id: [0], deliveryReceiptDetailsId:[0], itemCode:['', Validators.required], qtyReceived:[0, Validators.required], inputs: this.fb.array([this.CreateArray()]), }); // 从LocalStorage恢复数据 const savedForm = localStorage.getItem('serialFormTempData'); if (savedForm) { this.serialForm.setValue(JSON.parse(savedForm)); } // 监听表单变化,实时保存到LocalStorage this.serialForm.valueChanges.subscribe(formValue => { localStorage.setItem('serialFormTempData', JSON.stringify(formValue)); }); // 原有数量变化逻辑(补充减少数量时的处理) this.serialForm.get('qtyReceived')?.valueChanges.subscribe((res) => { const currentLength = this.displayArray.length; if (res > currentLength) { for (let i = currentLength; i < res; i++) { this.displayArray.push(this.CreateArray()); } } else if (res < currentLength) { // 数量减少时移除多余的输入行 while (this.displayArray.length > res) { this.displayArray.removeAt(this.displayArray.length - 1); } } }); // 初始化传入数据 this.serialForm.get('id')?.setValue(this.data.id); this.serialForm.get('qtyReceived')?.setValue(this.data.qtyReceived); this.serialForm.get('itemCode')?.setValue(this.data.propertyNo); }
2. IndexedDB
适合存储大量、结构化的临时数据,支持事务和索引,容量远大于LocalStorage(通常50MB以上),支持离线操作。
实现思路:可以使用Angular封装的库(如dexie-angular)简化操作,将表单数据存入IndexedDB;组件初始化时查询并恢复表单状态。
核心优势:处理复杂数据结构更灵活,适合需要离线保存大量数据的场景。
3. 后端会话级临时存储
如果需要跨设备同步临时数据,或数据需要和后端交互,可以将临时数据提交到后端的会话存储(如Redis)。
实现思路:
- 后端提供临时数据的保存/读取接口,通过用户会话(Token/Cookie)关联数据;
- 前端在表单变化时调用接口保存数据;
- 组件初始化时调用接口拉取会话内的临时数据。
修改SerialCodeService示例:
@Injectable({ providedIn: 'root' }) export class SerialCodeService { private url = 'api/serial/temp'; private headers = new HttpHeaders({ 'Content-Type': 'application/json' }); constructor(private http: HttpClient) { } // 保存临时数据 saveTempData(data: any): Observable<any> { return this.http.post(`${this.url}/save`, data, { headers: this.headers }); } // 获取临时数据 getTempData(): Observable<any> { return this.http.get(`${this.url}/get`, { headers: this.headers }); } }
组件中使用示例:
ngOnInit(): void { // ... 表单初始化逻辑 // 拉取后端临时数据 this.serialCodeService.getTempData().subscribe(savedData => { if (savedData) { this.serialForm.setValue(savedData); } }); // 表单变化时保存到后端 this.serialForm.valueChanges.subscribe(formValue => { this.serialCodeService.saveTempData(formValue).subscribe(); }); // ... 原有数量变化和数据初始化逻辑 }
4. Cookie存储
适合小体积临时数据(最大4KB),数据会随HTTP请求自动发送到后端,适合需要和后端共享的场景。
实现示例:
// 保存到Cookie(设置1小时过期) const formValueStr = encodeURIComponent(JSON.stringify(formValue)); document.cookie = `serialFormTemp=${formValueStr}; path=/; max-age=3600; SameSite=Lax`; // 读取Cookie const cookieEntry = document.cookie.split('; ').find(row => row.startsWith('serialFormTemp=')); if (cookieEntry) { const savedFormStr = decodeURIComponent(cookieEntry.split('=')[1]); const savedForm = JSON.parse(savedFormStr); this.serialForm.setValue(savedForm); }
内容的提问来源于stack exchange,提问作者Yan
相关产品推荐
相关产品推荐

