Kaynağa Gözat

Traversing metadata tree when used with nested formGroupName dirtectives

Richard Knight 6 yıl önce
ebeveyn
işleme
9a4323169e

+ 7 - 1
src/app/app.component.html

@@ -7,7 +7,13 @@
 			</p>
 		</div>
 	</div>
-	<app-dynaform [formGroup]="form" [meta]="meta" [template]="tref"></app-dynaform>
+	<form [formGroup]="form">
+		<span formGroupName="dynaformtest">
+			<span formGroupName="d">
+				<app-dynaform formGroupName="g" [meta]="meta" [template]="tref"></app-dynaform>
+			</span>
+		</span>
+	</form>
 	<div calss="row">
 		<div class="col-12 pt-4 pb-4">
 			<json-formatter [data]="form.value" open="4"></json-formatter>

+ 4 - 7
src/app/app.component.ts

@@ -2,7 +2,7 @@ import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 import { DynaformService } from './dynaform/services/dynaform.service';
 
-import { model, meta } from './_mock/testfields.v5';
+import { model, meta as lazyMeta } from './_mock/testfields.v5';
 
 @Component({
 	selector: 'app-root',
@@ -13,7 +13,6 @@ export class AppComponent implements OnInit {
 
 	form: FormGroup;
 	meta: StringMap;
-	formMetaDataObj: StringMap;
 
 	@ViewChild('testTemplate', { read: TemplateRef })
 	tref: TemplateRef<any>;
@@ -24,11 +23,9 @@ export class AppComponent implements OnInit {
 	}
 
 	ngOnInit() {
-		this.form = this.dynaform.build(model, meta);
-		this.meta = this.dynaform.autoBuildModeledMeta(model, meta);
-		console.log(this.form);
-		this.formMetaDataObj = {...this.meta};
-		console.log(this.formMetaDataObj);
+		({ form: this.form, meta: this.meta } = this.dynaform.build(model, lazyMeta));
+		console.dir(this.form);
+		console.dir(this.meta);
 	}
 }
 

+ 17 - 3
src/app/dynaform/dynaform.component.ts

@@ -65,12 +65,21 @@ export class DynaformComponent implements OnInit {
 			throw new Error('Dynaform Component initialised without [formGroup] or formGroupName');
 		}
 		this.controlNames = Object.keys(this.formGroup.controls);
-		// this.controlNames = Object.values(this.formMetaData).map((metaFoG: StringMap) => metaFoG.name);
-		// console.log(this.controlNames);
-		// console.log(this.formGroup);
+
+		// If we're given a formGroupName and the form's full metadata tree
+		// drill down to find the corresponding FormGroup's metadata
+		if (this.formGroupName) {
+			const path = this.cc.path.reverse();
+			const firstControlName = this.controlNames[0];
+			while (path.length && !this.formMetaData[firstControlName]) {
+				const branch = path.pop();
+				this.formMetaData = this.formMetaData[branch].meta;
+			}
+		}
 	}
 
 	getTemplateContext(controlName: string): DynarowContext {
+		/*
 		console.log('-------------------------------------');
 		console.log('getTemplateContext', controlName);
 		console.log(this.formGroup);
@@ -81,6 +90,11 @@ export class DynaformComponent implements OnInit {
 		};
 		console.log(context);
 		return context;
+		*/
+		return {
+			control: this.formGroup.get(controlName),
+			meta: this.formMetaData[controlName]
+		};
 	}
 
 	getRowClass(inputType: string): string {

+ 16 - 7
src/app/dynaform/services/dynaform.service.ts

@@ -3,8 +3,8 @@
 Dynaform Service, exposing 8 public methods
 ===========================================
 
-build(model, meta) - takes a model and (lazy)metadata and returns a FormGroup
-autoBuildFormGroup(model, meta) - synonym for autoForm
+build(model, meta) - takes a model and (lazy)metadata and returns aa an objevt { form: FormGroup, meta: ModeledMetaData }
+autoBuildFormGroupAndMeta(model, meta) - synonym for build
 autoBuildModeledMeta(model, meta) - takes a model and (lazy)metadata and returns expanded metadata
 
 buildFormGroup(metadata) - builds FormGroups from modelled metdata, recursively if necessary
@@ -40,6 +40,12 @@ import {
 	buildFieldSpecificMeta, buildFormGroupFunctionFactory
 } from './meta-utils';
 
+export interface FormAndMeta {
+	form: FormGroup;
+	meta: StringMap;
+}
+
+
 @Injectable()
 export class DynaformService {
 
@@ -52,14 +58,17 @@ export class DynaformService {
 	// -----------------------------------------------------------------------------------------------------------------
 	// Convenience methods combining several steps
 
-	build(model, meta = {}): FormGroup {
-		// Shortname for autoBuildFormGroup
-		return this.autoBuildFormGroup(model, meta);
+	build(model, meta = {}): FormAndMeta {
+		// Short name for autoBuildFormGroupAndMeta
+		return this.autoBuildFormGroupAndMeta(model, meta);
 	}
 
-	autoBuildFormGroup(model, meta = {}): FormGroup {
+	autoBuildFormGroupAndMeta(model, meta = {}): FormAndMeta {
 		const modelWithMeta = this.autoBuildModeledMeta(model, meta);
-		return this.buildFormGroup(modelWithMeta);
+		return {
+			form: this.buildFormGroup(modelWithMeta),
+			meta: modelWithMeta
+		};
 	}
 
 	autoBuildModeledMeta(model, meta = {}) {