TNG / ngqp

Declaratively synchronize form controls with the URL
https://tng.github.io/ngqp
MIT License
81 stars 8 forks source link

Switch multi property #154

Closed Duke-Rong closed 4 years ago

Duke-Rong commented 4 years ago

What's your idea?

In the case of binding one queryParam one select box with two situations: multi selection & single selection, there are conflicts using one queryParam because of the mulit property only works on multi selection situation. Is it possible to make multi changeable?

 <p-multiSelect
         *ngIf="!isSingle()"
         queryParamName="sources"
         [formControl]="processingForm.controls['sources']"
         >
 </p-multiSelect>

 <p-dropdown
           *ngIf="isSingle()"
            queryParamName="sources"
             [options]="sources"
             [formControl]="processingForm.controls['sources']"
 >
 </p-dropdown>

    this.paramGroup = this.qpb.group({
        sources: this.qpb.param('sources', {
            multi: true,
            serialize: (value: Object): string => {
                return JSON.stringify(value);
            },
            deserialize: (value: string): Object => {
                return JSON.parse(value);
            }
        })
    });

Describe the solution you'd like

Add an api such as this.paramGroup.setProperty('sources', { multi: false})

Airblader commented 4 years ago

Hi, thanks for opening this issue. Is the isSingle() decided once when the component loads, or can this change at any point in time?

Duke-Rong commented 4 years ago

Sorry for the late reply. It could be changed all the time. I believe it is one of the situation of # #145

Airblader commented 4 years ago

It could be changed all the time.

I think that would make it awkward if you currently have a multi: true query param with a value of [1, 2] and now want to disable multi. ngqp couldn't know what you'd want to do with the value, and any strategy like "pick the first one" seems like a workaround.

However, can't you do something like this for your case?

private singleParam = this.qpb.param('p');
private multiParam = this.qpb.param('p', {multi: true});

private paramGroup = this.qpb.group({
    param: singleParam,
});

switchParam(multi: boolean) {
    const currentParam = this.paramGroup.get("param");
    this.paramGroup.remove("param");

    const newParam = multi ? this.multiParam : this.singleParam;
    // This probably requires a type assertion, I cannot actually try it out right now
    newParam.setValue(currentParam.value);
    this.paramGroup.add("param", newParam);
}

On a side note, ngqp doesn't usually work well in combination with template-driven or reactive forms (you're using both queryParamName and formControl).

Duke-Rong commented 4 years ago

Yea, it is a good idea to drop the old one and add a new one without multi property. I will try that out and hope it works. Thank you for your help! :)

Airblader commented 4 years ago

You're welcome! Once you have tried it out please feel free to post back here whether it worked / what else was needed to make it work.

I'll close this issue for now given that solution and the fact that I don't think the original feature can be implemented in a nice way. We can certainly reconsider if the solution above doesn't work out.

Duke-Rong commented 4 years ago

I forgot to leave the feedback! The remove / add new control works, just need to find the correct time to do so.