Closed KBroichhausen closed 1 year ago
I just realisied that in my full application the two-way data binding is still not working for some values. So, this patch working in the reprox is probably just a side effect and not eliminating the problem.
@KBroichhausen in my opinion, the only effect of disctinctUntilChanged
here is to ignore some values (the ones being identical to the last value), so it means that, somehow, we emit multiple times the same value and it results in a bad behavior.
Probably the non-working case is not about the value not being changed but changed and then changed bacl to the previous value. Don't you think? (nevertheless I have no idea either why or how 😓)
Regarding your last comment: do you still want to merge this fix (as it is not eliminating the problem entirely)? On my side, I am fine merging it considering it is a very small change that should not make any unwanted side-effect anyway.
Well, I think using distinctUntilChanged
is a good idea at that place because I see calls all over the place without it. Also it is much faster in my full application.
Without distinctUntilChanged
and in the minimal example, I can see that in onValueChanges
of FormComponent
the model is already set back to the initial non-modified state. And I just added some logs to the ControlWidget
. Without distinctUntilChanged
my change in the model is not populated there but with distinctUntilChanged
it is. This happens before onValueChanges
.
Which imho means that it is somehow manipulated before. Due to the nature of asynchronous code it is really hard to debug and to tell what is going on.
Btw with the distinctUntilChanged
fix, I got my application to work with a stupid workaround:
for (let i = 0; i < 5; i++) {
this.model = JSON.parse(fileReader.result.toString());
this.cdr.markForCheck();
this.cdr.detectChanges();
}
Where cdr
is ChangeDetectorRef
. Maybe this is a different problem. It looks like all the visibleIf
subscription are removing stuff from the model before it is fully evaluated, that's why I need to load it multiple times. Hence this does not really explain why some fields are not filled, which are always visible, but gets filled with the workaround.
So, technically this could be merged but it's not removing the root cause of this issue. 😉
Well, I guess the best approach would be to move all the components to changeDetection: ChangeDetectionStrategy.OnPush
so we can have full control.
With the default strategy we are using at the moment, we just rely on Angular to do its best, but here is a typical case where it is not good enough.
Your fix with ChangeDetectorRef
sounds totally fine to me (I have to do the same with many external libs quite often)
Once again a pull request by me. I have no idea why this patch is working and I really like to discuss that because I don't like to blindly provide patches where I don't know why they are working.
How to reproduce?
In this reprox https://stackblitz.com/edit/angular-ivy-cxvsbz?file=src/app/app.component.ts click
Press to change
and see that the child object inNon working
is not changed toDesc. of child element 2
but in the second form inWorking
it is changed toDesc. of child element 2
.What's the difference?
The non working schema uses
allOf
invisibleIf
while the second just usesvisibleIf
withoutallOf
oroneOf
What's the patch doing?
It simply a one liner where I change from
subscribe
topipe
withdisctinctUntilChanged
within the binding function forallOf
andoneOf
. That's the same way as it is done when providing nothing forvisibleIf
(that's how I get to this solution).Is this a regression?
No. Even I nearly complete have rewritten the
oneOf
andallOf
binding myself in my last pull request, you can use version2.8.1
and2.8.2
in my reprox withouth any change. In2.8.1
the subscription was done the same way as in the newer2.8.2
version with my rewrite: https://github.com/guillotinaweb/ngx-schema-form/blob/410b38dda91428dc44ecd3b1c8d60ad1ce829f1e/projects/schema-form/src/lib/model/formproperty.ts#L372-L379What's happening?
So, I have really no idea why it works with my patch. What I think I understand so far, is that somehow the different subscription overwrites the data in the model when changed. But why and how does this work? See the output where the non working schema output before a change, then after change and then after a timeout of 1 second where it is back in the state before.![grafik](https://user-images.githubusercontent.com/38033805/186405495-10840ad2-e641-4e49-96b3-69f5a04d949d.png)