@@ -23,6 +23,7 @@ import findNearestPrefixFromArray from "../utils/find-nearest-prefix-from-array"
23
23
import AvailabilityEvent from "./AvailabilityEvent" ;
24
24
import bypassObject from "../utils/bypass-object" ;
25
25
import isIterablePoint from "../utils/is-iterable-point" ;
26
+ import FormError from "./FormError" ;
26
27
27
28
/**
28
29
* Main principe : GMN
@@ -63,7 +64,6 @@ export default class Form extends EventEmitter implements FormDependence {
63
64
if ( elem . parent ) return `${ Form . restoreFullName ( elem . parent ) } .${ elem . name } ` ;
64
65
return elem . name || '' ;
65
66
}
66
-
67
67
static getTargetName < T extends { name ?: string , parent ?: any } > ( elem : T ) : string {
68
68
const array = [ ] ;
69
69
@@ -80,19 +80,40 @@ export default class Form extends EventEmitter implements FormDependence {
80
80
* @description Name of Entity.
81
81
* */
82
82
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
+
83
104
/**
84
105
* @description Внутренний объект изменений. Хранит в себе значения полей, которые были установлены, используя флаг
85
106
* changes: true в методе setValues или используя метод change.
86
107
* */
87
108
#changes = { } ;
88
109
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 ) ) ;
90
111
return this . #changes;
91
112
}
92
113
93
114
#values = { }
94
115
get values ( ) : any {
95
- if ( this . parent ) {
116
+ if ( this . parent && ! this . autonomic ) {
96
117
return this . parent . getValueByName ( this . name as string ) || { } ;
97
118
}
98
119
return mergeObjects ( { } , this . #values, this . #changes)
@@ -101,7 +122,7 @@ export default class Form extends EventEmitter implements FormDependence {
101
122
* @description Чистые значения формы. Которые изменяются при помощи setValues без опции change.
102
123
* */
103
124
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 ) || { }
105
126
return this . #values;
106
127
}
107
128
@@ -126,20 +147,23 @@ export default class Form extends EventEmitter implements FormDependence {
126
147
this . #parent = parent ;
127
148
}
128
149
150
+ /**
151
+ * !!!!!!!!!!!
152
+ * CONSTRUCTOR
153
+ * !!!!!!!!!!!
154
+ */
129
155
constructor ( params : Partial < FormParams > = { } ) {
130
156
super ( ) ;
131
157
132
158
this . name = params . name ;
133
159
const currentInstance = ! ! getCurrentInstance ( ) ;
134
-
135
160
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 ) ;
142
164
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 ;
143
167
}
144
168
145
169
setValues ( values : any , options : Partial < FormSetValuesOptions > = { } ) : void {
@@ -155,13 +179,13 @@ export default class Form extends EventEmitter implements FormDependence {
155
179
if (!checkNameInObject(values, target)) insertByName(values, target)
156
180
*/
157
181
158
- if ( ! options . executedFrom ) {
182
+ if ( ! options . executedFrom && ! this . autonomic ) {
159
183
debug . msg ( `Executed from not founded in options, values will be %c${ Form . getTargetName ( this ) } ` , debug . colorSuccess )
160
184
options . executedFrom = Form . getTargetName ( this ) ;
161
185
}
162
186
163
187
// Текущий элемент имеет родителя - отправляем изменения наверх.
164
- if ( this . parent ) {
188
+ if ( this . parent && ! this . autonomic ) {
165
189
debug . msg ( `%c${ this . name } %c emit changes to parent [%c${ this . parent . name } %c]` , debug . colorName , debug . colorDefault , debug . colorFocus , debug . colorDefault ) ;
166
190
return void this . parent . setValues ( values , options ) ;
167
191
}
@@ -395,8 +419,13 @@ export default class Form extends EventEmitter implements FormDependence {
395
419
/**
396
420
* @description Return true if form includes changes, otherwise false.
397
421
* */
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
+ ) ;
400
429
}
401
430
402
431
subscribe ( element : any ) {
@@ -494,7 +523,7 @@ export default class Form extends EventEmitter implements FormDependence {
494
523
* для данного поля будет стёрто из объекта changes.
495
524
* */
496
525
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 ) ) ;
498
527
499
528
// Если значение есть в pureValues - устанавливаем его
500
529
// Иначе undefined
@@ -512,7 +541,7 @@ export default class Form extends EventEmitter implements FormDependence {
512
541
revert ( ) {
513
542
debug . msg ( 'revert changes' ) ;
514
543
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 ) ;
516
545
517
546
this . setValues ( this . pureValues , {
518
547
change : true ,
@@ -670,7 +699,7 @@ export default class Form extends EventEmitter implements FormDependence {
670
699
return ! this . enabled ;
671
700
}
672
701
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 ) ;
674
703
return this . isAvailable ;
675
704
}
676
705
@@ -700,7 +729,7 @@ export default class Form extends EventEmitter implements FormDependence {
700
729
* Далее передаём объект в dispatchEvent.
701
730
* */
702
731
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 ] )
704
733
debug . group ( `AVAILABILITY %c${ Form . getTargetName ( this ) } %c to %c${ type } ` , debug . colorName , debug . colorDefault , debug . colorFocus ) ;
705
734
706
735
const oldAvailable = this . isAvailable ;
@@ -754,7 +783,7 @@ export default class Form extends EventEmitter implements FormDependence {
754
783
* @description Вернёт true, если переданное поле является disabled.
755
784
* */
756
785
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 ) ) ;
758
787
const nearestName = findNearestNameFromArray ( Object . keys ( this . #availabilities) , fieldName ) ;
759
788
if ( ! nearestName ) return this . disabled ;
760
789
@@ -784,7 +813,12 @@ export default class Form extends EventEmitter implements FormDependence {
784
813
interface FormParams {
785
814
name : string ,
786
815
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
788
822
}
789
823
790
824
interface FormDependence {
0 commit comments