TNG/ngqp

Binding one component to multiple parameters

Airblader opened this issue · 2 comments

What's your idea?

Imagine a select representing how to sort something. You might have the same attributes listed twice, once for ascending and descending each. It's easy to serialize this to the URL as ?sort=attr_asc at the moment, but what if we want ?sort=attr&order=asc instead?

Describe the solution you'd like

Perhaps a viable solution would be to provide some wrapping component/directive which can take an array of queryParamName, some function(s) on how to do the (de-)serializer splitting and implements a ControlValueAccessor that redirects to the actual underlying component.

This is a very rough idea I haven't thought through yet. Alternative ideas or concrete proposals are welcome.

I've played with two ideas:

  1. Continue using queryParamName, but allow the input to be an array of strings. Then manage a new concept of "accessor groups" in the orchestrating service. This does make things pretty complicated, also since each param can be bound to multiple components.

I decided that the complexity here probably isn't justified and that we should look for better alternatives.


  1. Add a new directive which looks something like
<select [queryParamNames]="['sortBy', 'sortDirection']" 
        [inflate]="fnInflate" [deflate]="fnDeflate">
  <option value="name_asc">Name (A→Z)</option>
</select>

with fnInflate: (value: unknown) => unknown[] and fnDeflate: (values: unknown[]) => unknown. This directive would expose a new ControlValueAccessor on the host which memorizes the latest values of all managed parameters and combines them whenever something updates.

There's two open points:

  1. We need access to the "actual" ControlValueAccessor so we can wire them up.
  2. We'd probably need a way for the user to select the correct ControlValueAccessor to be used, or we change selectControlValueAccessor to always prefer our special one.

One way to achieve this would be to just inject the accessors and filter out our own.

Additional note: theoretically, we could still use only one directive here and just omit the plural.

Yet another idea: splitting it in the model already, e.g.

this.paramGroup = this.qpb.group({
    sorting: qpb.combine([
      qpb.stringParam('sortBy'),
      qpb.stringParam('sortDirection'),
    ], { inflate, deflate }),
});