Skip to content

Commit

Permalink
test: form-proxy subscribe to form.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenesius committed May 14, 2023
1 parent 26763f5 commit 1089280
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 31 deletions.
10 changes: 10 additions & 0 deletions docs/guide/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Почему значения нужно рекурсивно копировать?

Может возникнуть вопрос, почему в форме у нас есть переменная values, которая является чистым хранилищем
значений, почему нельзя реализовать её как гетер и проходить по всем зависимостям и получать их значение.
Это решение позволяет обойти 2 проблемы:

1. При удалении поля для ввода - будет теряться его значение
2. Как поступать, если в начале мы инициализировали форму `form.setValues(data)`, а затем добавили input.

Именно данная подход сосредоточить модель в одном месте, позволяет упростить разработку.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jenesius-vue-form",
"version": "2.3.20",
"version": "2.3.21",
"description": "Heavy form system for Vue.js",
"author": "Jenesius",
"license": "MIT",
Expand Down
32 changes: 28 additions & 4 deletions plugin/classes/Form.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import EventEmitter from "jenesius-event-emitter";
import {inject as injectVue, provide as provideVue} from "vue";
import {getCurrentInstance, inject as injectVue, provide as provideVue} from "vue";
import FormErrors from "./FormErrors";
import {FormDependence, FunctionHandleData, Value, Values} from "../types";

Expand Down Expand Up @@ -124,6 +124,7 @@ export default class Form extends EventEmitter implements FormDependence{
* @return true - if #changes includes some values or one of dependencies stay in changed status.
*/
get changed() {
if (this.parentForm && this.name) return this.parentForm.checkDependenceForChangedStatus(this.name);
return !!Object.keys(this.#changes).length || !!this.dependencies.find(d => d.changed);
}

Expand Down Expand Up @@ -157,6 +158,7 @@ export default class Form extends EventEmitter implements FormDependence{
* @description Method used for set values. New values don't overwrite previous, Mixing, GrandValues used for this.
* */
setValues(values?: Values){

const prettyData = grandObject(values);
debug.msg(`New Values:`, prettyData);

Expand All @@ -174,14 +176,17 @@ export default class Form extends EventEmitter implements FormDependence{
this.name = params.name;
debug.msg(`Creating new Form${this.name? `[${this.name}]`: ''}`);

const currentInstance = !!getCurrentInstance()

// If params don't include parent: false, looking for a form, in case of success subscribe current form to parent.
if (params.parent !== false) {
this.parentForm = Form.getParentForm();
if (currentInstance)
this.parentForm = Form.getParentForm();
if (this.parentForm) this.parentForm.subscribe(this);
}

provideVue(Form.PROVIDE_NAME, this); // Default providing current form for children.
if (currentInstance)
provideVue(Form.PROVIDE_NAME, this); // Default providing current form for children.
}

private markChanges(values: any) {
Expand Down Expand Up @@ -269,8 +274,19 @@ export default class Form extends EventEmitter implements FormDependence{
}

change(values?: Values){
if (this.parentForm && this.name) {
this.parentForm.change({
[this.name]: {
...this.values,
...values
}
})
return;
}

this.setValues(values);
if (values) this.markChanges(values);

}

protected setValuesByName(name: string, value: any) {
Expand Down Expand Up @@ -305,6 +321,7 @@ export default class Form extends EventEmitter implements FormDependence{
* @description Merging values.
* */
protected mergeValues(values: Values) {
console.log(this.values, values)
mergeObjects(this.values, values);
}

Expand All @@ -315,8 +332,15 @@ export default class Form extends EventEmitter implements FormDependence{
debug.msg(`New subscription${'name' in item ? `(${item.name})` : ''}`)

this.dependencies.push(item);
this.emit(Form.EVENT_SUBSCRIBE, item);

// Install parentForm to this
try {
item.parentForm = this;
} catch (e) {

}

this.emit(Form.EVENT_SUBSCRIBE, item);

try {
item.on(Form.EVENT_CHANGED, () => this.emit(Form.EVENT_CHANGED, this.changed));
Expand Down
2 changes: 1 addition & 1 deletion plugin/classes/FormProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default class FormProxy extends Form{
* @description Get values just for current names from parent form.
*/
get values() {
return getPropFromObject(this.parentForm?.values, this.name);
return getPropFromObject(this.parentForm?.values, this.name) || {};
}

/**
Expand Down
17 changes: 0 additions & 17 deletions plugin/utils/soft-replace-object.ts

This file was deleted.

2 changes: 0 additions & 2 deletions plugin/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import checkCompositeName from "./check-composite-name";
import bypassObject from "./bypass-object";
import convertOptionsObject from "./convert-options-object";
import copyObject from "./copy-object";
import softReplaceObject from "./soft-replace-object";

const utils = {
updateInputPosition,
Expand All @@ -35,6 +34,5 @@ const utils = {
bypassObject,
convertOptionsObject,
copyObject,
softReplaceObject
}
export default utils;
5 changes: 0 additions & 5 deletions src/pages/test/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@

<input-field type = "coord" name = "coordinate"/>

<input-coord name="coordinate" />

<input-field name = "file" type = "file"/>

</div>
</template>

Expand All @@ -24,7 +20,6 @@ const form = new Form();
function test() {
throw new Error('test')
}
Expand Down
7 changes: 6 additions & 1 deletion src/pages/test/input-coord.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div>
<input-field name = "X" label = "X"/>
<input-field name = "Y" label = "Y"/>

<button @click = "random">test</button>
{{values}}
</div>
</template>
Expand All @@ -14,6 +14,11 @@ const props = defineProps<{
name: string,
}>()
const {form} = useProxyState(props.name)
function random() {
form.change({
X: Math.random()
})
}
const values = useFormValues(form)
</script>
Expand Down
70 changes: 70 additions & 0 deletions tests/form-proxy/subscribe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {Form, FormProxy} from "../../plugin";

describe("Default test For FormProxy", () => {

test("Values of parent form should be changed", () => {
const parentForm = new Form();

const form = new FormProxy({
name: "address"
})
parentForm.subscribe(form);

parentForm.setValues({
name: "jenesius"
})

form.change({
city: "XXX"
})
expect(parentForm.values).toEqual({
address: {
city: "XXX"
},
name: "jenesius"
})
expect(parentForm.changes).toEqual({
address: {
city: "XXX"
}
})
})
test("Changed prop must be true after change", () => {
const parentForm = new Form();

const form = new FormProxy({
name: "address"
})
parentForm.subscribe(form);

expect(form.changed).toBe(false);
expect(parentForm.changed).toBe(false);

form.change({
city: "XXX"
})

expect(parentForm.changed).toBe(true)
expect(form.changed).toBe(true);

})
/*
test("New values after setValues", () => {
const parentForm = new Form();
const form = new FormProxy({
name: "address"
})
parentForm.subscribe(form);
form.setValues({
planet: "Earth"
})
expect(parentForm.values).toEqual({
address: {
planet: "Earth"
}
})
})*/
})

0 comments on commit 1089280

Please sign in to comment.