angular-schema-form icon indicating copy to clipboard operation
angular-schema-form copied to clipboard

Don't modify form or schema

Open davidlgj opened this issue 10 years ago • 9 comments

Related to #395

Incoming form definition objects are reused and in case of some defaults the schema might be changed as well. We should make a copy to use internally.

davidlgj avatar May 29 '15 09:05 davidlgj

What would you do if the user updates theirs, re-process? What if they have a decorator that makes changes? Just thinking out loud...

Anthropic avatar May 29 '15 09:05 Anthropic

Currently we re-process when a ordinary watch changes it, i.e. the schema object instance or form array is changed (ordinary ===). Or if you issue a schemaFormRedraw event. I don't want to change that, just that the scope.form used in the isolated scope is a deep copy of outside form as well as the schema so that the "original" form definition and schema isn't changed by schema form.

This probably needs to be optional, since in certain cases you can change part of your form, ex. description and it will update without needing to re-render the form (I never designed it to be able to do that, but angular 1.2 support forced me to not use ::, so now people are doing it I guess it's best not to break it). Basically it's hard supporting both being able to swap out the schema and modification to the form after rendering.

davidlgj avatar May 29 '15 10:05 davidlgj

Perhaps this is a related issue. I have created a form editor. I noticed an odd behavior. I store the form def and form schema in a subkey of a larger JSON. If I specify the form and schema, for some reason any form element keys are changed from say key: "description" to key: ["description"]. So I thought "okay let's clone it" and use JQuery's extend to create a deep copy. Unfortunately only the initial extend causes the form display to update. Subsequent changes do not cause the form to be redrawn. As a result added or changed fields are not reflected in the "preview" where I display a hidden div to render the form being created. Any suggestions or clues?

rayhooker avatar Jun 09 '15 23:06 rayhooker

@rayhooker Yes this is the exact same problem. Schema Form messes with the form definition internally, massaging it in to a "canonical" form. Redraws of form is only done if the instance of the object changes, not just a property. See https://github.com/Textalk/angular-schema-form/blob/development/docs/index.md#updating-form

So the solution for you is to issue a scope.$broadcast('schemaFormRedraw') after a change to propagate it to the preview.

davidlgj avatar Jun 12 '15 07:06 davidlgj

I noticed that this also affects the way the 'key'-value gets stored. I had a couple of keys containing '.' (dots).

  "model": {
    "Field.SystemSettingExchange.ExchangeEnabled": true,
    //etc... 

I add these exact same keys to the form like this:

$scope.form.push({
  'key': fieldEntry.key,
  'type': fieldEntry.type
});

and they come out in a array, which breaks the coupling with the model, among other things:

  "form": [
    {
      "key": [
        "Field",
        "SystemSettingExchange",
        "ExchangeEnabled"
      ]
    },
   //etc...

tuvokki avatar Sep 21 '15 11:09 tuvokki

@tuvokki yes that id the internal format. The wok being done on PR #505 means that we really need to make a copy of schema and form. So it will probably be fixed soon

davidlgj avatar Sep 21 '15 11:09 davidlgj

That's great to hear. I've changed my backend to remove the dots so I can test my use-case easily if this is done. Let me know if I can help out.

tuvokki avatar Sep 21 '15 13:09 tuvokki

Was this fixed? I am having the same problem. I am building dynamic forms and I need my form objects left unchanged so I can reproduce forms at a later date. Schema Form keeps changing my keys to arrays whenever I render.

tjones0808 avatar Aug 31 '16 12:08 tjones0808

@tjones0808 I just had a quick look and I would expect if you search in the compiled file for initialForm and find the line: var form = scope.initialForm || [ '*' ]; And replace it with var form = scope.initialForm ? angular.copy(scope.initialForm) : [ '*' ]; it was like that in another line so should have the desired effect.

I will look at adding it to the next release. Please let me know if that was all that was required!

To be honest it seems too easy, I suspect I am missing something.

Anthropic avatar Oct 04 '16 13:10 Anthropic