@@ -23,6 +23,7 @@ import findNearestPrefixFromArray from "../utils/find-nearest-prefix-from-array"
2323import AvailabilityEvent from "./AvailabilityEvent" ;
2424import bypassObject from "../utils/bypass-object" ;
2525import isIterablePoint from "../utils/is-iterable-point" ;
26+ import FormError from "./FormError" ;
2627
2728/**
2829 * Main principe : GMN
@@ -63,7 +64,6 @@ export default class Form extends EventEmitter implements FormDependence {
6364 if ( elem . parent ) return `${ Form . restoreFullName ( elem . parent ) } .${ elem . name } ` ;
6465 return elem . name || '' ;
6566 }
66-
6767 static getTargetName < T extends { name ?: string , parent ?: any } > ( elem : T ) : string {
6868 const array = [ ] ;
6969
@@ -80,19 +80,40 @@ export default class Form extends EventEmitter implements FormDependence {
8080 * @description Name of Entity.
8181 * */
8282 name ?: string
83+ /**
84+ * @description If set to true, then values,changes are standalone and independent of the parent form.
85+ */
86+
87+ #autonomic: boolean | undefined = undefined ;
88+ /**
89+ * @description Класс является автономным, если не указан родитель или если свойство #autonomic установлено в true
90+ */
91+ get autonomic ( ) :boolean {
92+ // Если есть родитель, то проверяем на autonomic
93+ if ( this . parent ) return this . #autonomic === true ;
94+ // Родитель отсутствует, в таком случае форма всегда является автономной
95+ return true ;
96+ }
97+ set autonomic ( value : boolean ) {
98+ if ( value === false && ! this . parent ) throw FormError . AutonomicFormWithoutParent ( ) ;
99+ this . #autonomic = value ;
100+
101+ debug . msg ( `The form's %c${ Form . restoreFullName ( this ) } %c autonomic is %c${ value } %c.` ) ;
102+ }
103+
83104 /**
84105 * @description Внутренний объект изменений. Хранит в себе значения полей, которые были установлены, используя флаг
85106 * changes: true в методе setValues или используя метод change.
86107 * */
87108 #changes = { } ;
88109 get changes ( ) : any {
89- if ( this . parent ) return getPropFromObject ( this . parent . changes , Form . getTargetName ( this ) ) ;
110+ if ( this . parent && ! this . autonomic ) return getPropFromObject ( this . parent . changes , Form . getTargetName ( this ) ) ;
90111 return this . #changes;
91112 }
92113
93114 #values = { }
94115 get values ( ) : any {
95- if ( this . parent ) {
116+ if ( this . parent && ! this . autonomic ) {
96117 return this . parent . getValueByName ( this . name as string ) || { } ;
97118 }
98119 return mergeObjects ( { } , this . #values, this . #changes)
@@ -101,7 +122,7 @@ export default class Form extends EventEmitter implements FormDependence {
101122 * @description Чистые значения формы. Которые изменяются при помощи setValues без опции change.
102123 * */
103124 get pureValues ( ) :any {
104- if ( this . parent ) return getPropFromObject ( this . parent . pureValues , this . name as string ) || { }
125+ if ( this . parent && ! this . autonomic ) return getPropFromObject ( this . parent . pureValues , this . name as string ) || { }
105126 return this . #values;
106127 }
107128
@@ -126,20 +147,23 @@ export default class Form extends EventEmitter implements FormDependence {
126147 this . #parent = parent ;
127148 }
128149
150+ /**
151+ * !!!!!!!!!!!
152+ * CONSTRUCTOR
153+ * !!!!!!!!!!!
154+ */
129155 constructor ( params : Partial < FormParams > = { } ) {
130156 super ( ) ;
131157
132158 this . name = params . name ;
133159 const currentInstance = ! ! getCurrentInstance ( ) ;
134-
135160 debug . msg ( `new form %c${ Form . restoreFullName ( this ) } %c` , debug . colorName , debug . colorDefault , this ) ;
136- if ( currentInstance ) {
137- const parent = Form . getParentForm ( ) ;
138- if ( parent && ! ( params . parent === false || params . parent === null ) ) {
139- parent . subscribe ( this ) ;
140- }
141- }
161+
162+ const parent = ( currentInstance ? Form . getParentForm ( ) : null ) || params . parent
163+ if ( parent ) parent . subscribe ( this ) ;
142164 if ( params . provide !== false && currentInstance ) provideVue ( Form . PROVIDE_NAME , this ) ; // Default providing current form for children.
165+
166+ if ( typeof params . autonomic === 'boolean' ) this . autonomic = params . autonomic ;
143167 }
144168
145169 setValues ( values : any , options : Partial < FormSetValuesOptions > = { } ) : void {
@@ -155,13 +179,13 @@ export default class Form extends EventEmitter implements FormDependence {
155179 if (!checkNameInObject(values, target)) insertByName(values, target)
156180 */
157181
158- if ( ! options . executedFrom ) {
182+ if ( ! options . executedFrom && ! this . autonomic ) {
159183 debug . msg ( `Executed from not founded in options, values will be %c${ Form . getTargetName ( this ) } ` , debug . colorSuccess )
160184 options . executedFrom = Form . getTargetName ( this ) ;
161185 }
162186
163187 // Текущий элемент имеет родителя - отправляем изменения наверх.
164- if ( this . parent ) {
188+ if ( this . parent && ! this . autonomic ) {
165189 debug . msg ( `%c${ this . name } %c emit changes to parent [%c${ this . parent . name } %c]` , debug . colorName , debug . colorDefault , debug . colorFocus , debug . colorDefault ) ;
166190 return void this . parent . setValues ( values , options ) ;
167191 }
@@ -395,8 +419,13 @@ export default class Form extends EventEmitter implements FormDependence {
395419 /**
396420 * @description Return true if form includes changes, otherwise false.
397421 * */
398- get changed ( ) {
399- return ! ! ( this . changes && Object . keys ( this . changes ) . length !== 0 ) ;
422+ get changed ( ) : boolean {
423+ return ! ! (
424+ ( this . changes && Object . keys ( this . changes ) . length !== 0 )
425+ || this . dependencies . find (
426+ elem => ( elem instanceof Form && elem . changed )
427+ )
428+ ) ;
400429 }
401430
402431 subscribe ( element : any ) {
@@ -494,7 +523,7 @@ export default class Form extends EventEmitter implements FormDependence {
494523 * для данного поля будет стёрто из объекта changes.
495524 * */
496525 cleanChangesByField ( fieldName : string ) : void {
497- if ( this . parent ) return void this . parent . cleanChangesByField ( concatName ( this . name , fieldName ) ) ;
526+ if ( this . parent && ! this . autonomic ) return void this . parent . cleanChangesByField ( concatName ( this . name , fieldName ) ) ;
498527
499528 // Если значение есть в pureValues - устанавливаем его
500529 // Иначе undefined
@@ -512,7 +541,7 @@ export default class Form extends EventEmitter implements FormDependence {
512541 revert ( ) {
513542 debug . msg ( 'revert changes' ) ;
514543
515- if ( this . parent ) return void this . parent . cleanChangesByField ( this . name as string ) ;
544+ if ( this . parent && ! this . autonomic ) return void this . parent . cleanChangesByField ( this . name as string ) ;
516545
517546 this . setValues ( this . pureValues , {
518547 change : true ,
@@ -670,7 +699,7 @@ export default class Form extends EventEmitter implements FormDependence {
670699 return ! this . enabled ;
671700 }
672701 get enabled ( ) {
673- if ( this . parent ) return ! this . parent . checkFieldDisable ( this . name as string ) ;
702+ if ( this . parent && ! this . autonomic ) return ! this . parent . checkFieldDisable ( this . name as string ) ;
674703 return this . isAvailable ;
675704 }
676705
@@ -700,7 +729,7 @@ export default class Form extends EventEmitter implements FormDependence {
700729 * Далее передаём объект в dispatchEvent.
701730 * */
702731 available ( type : boolean , names : string [ ] ) :void {
703- if ( this . parent ) return this . parent . available ( type , names . length ? names . map ( k => concatName ( this . name , k ) ) : [ this . name as string ] )
732+ if ( this . parent && ! this . autonomic ) return this . parent . available ( type , names . length ? names . map ( k => concatName ( this . name , k ) ) : [ this . name as string ] )
704733 debug . group ( `AVAILABILITY %c${ Form . getTargetName ( this ) } %c to %c${ type } ` , debug . colorName , debug . colorDefault , debug . colorFocus ) ;
705734
706735 const oldAvailable = this . isAvailable ;
@@ -754,7 +783,7 @@ export default class Form extends EventEmitter implements FormDependence {
754783 * @description Вернёт true, если переданное поле является disabled.
755784 * */
756785 checkFieldDisable ( fieldName : string ) : boolean {
757- if ( this . parent ) return this . parent . checkFieldDisable ( concatName ( this . name , fieldName ) ) ;
786+ if ( this . parent && ! this . autonomic ) return this . parent . checkFieldDisable ( concatName ( this . name , fieldName ) ) ;
758787 const nearestName = findNearestNameFromArray ( Object . keys ( this . #availabilities) , fieldName ) ;
759788 if ( ! nearestName ) return this . disabled ;
760789
@@ -784,7 +813,12 @@ export default class Form extends EventEmitter implements FormDependence {
784813interface FormParams {
785814 name : string ,
786815 provide : boolean ,
787- parent : Form | null | false
816+ parent : Form | null | false ,
817+ /**
818+ * @description The form will be self-contained. They want and will have the opportunity to receive higher education
819+ * from their parents, however values, changes, enabling and disabling will be stored inside this form.
820+ */
821+ autonomic : boolean
788822}
789823
790824interface FormDependence {
0 commit comments