hansmaad / ng-units

Angular component library for units of measurement
https://hansmaad.github.io/ng-units/
MIT License
3 stars 3 forks source link

Feature Request: change unit in directive #19

Closed meta-space closed 3 years ago

meta-space commented 3 years ago

Some units like Temperature, are typically the same throughout the application and it makes sense to configure them in SystemOfUnits service. Others like time, length, etc. may differ within the same page.

It would be great if it were possible to specify the unit on the ngQuantity directive, like ngQuantity="time:s" or "length:km" The setting in the directive should probably be local and should override (but not change) the unit in the global SystemOfUnits.

hansmaad commented 3 years ago

Good idea, but I think it's better to have a separate binding for the unit like

<input ngQuantity="time" unit="s" >
<input ngQuantity="time" [unit]="myTimeUnit" >
<input [ngQuantity]="myQuantity" [unit]="myUnit" >
{{ value | ngQuantity:'time':'s' }}
meta-space commented 3 years ago

Coincidentally that is what I ended up doing in my custom quantity directive.

However, I fear my implementation may no be optimal. I retrieve the Quantity instance from the SystemOfUnits. If the unit needs to be changed, I create a local copy of Quantity & then call SelectUnit on the copy. This way the SystemOfUnits is never affected by any directive, but I am copying Quantities around.

@Input('ngQty)
quantityAttr!: string | Quantity;
@Input('ngUnit')
ngUnit: string | undefined;
 ...

 private initQuantity(): void {
     this.unsubscribe();

     let quantity = typeof this.quantityAttr === 'string' ? this.system.get(this.quantityAttr) : this.quantityAttr;
     if (this.ngUnit) {
       const unit = quantity.findUnit(this.ngUnit as string);
       if (quantity.unit !== unit) {
         quantity = Object.assign(new Quantity(), quantity);
         quantity.selectUnit(unit);
       }
     }
     this.quantity = quantity;
     this.subscribe();
     this.updateUnit();
 }
hansmaad commented 3 years ago

Finally Shipped in 11.0.0 Usage

<input [(ngModel)]="value" ngQuantity="Temperature" ngUnit="°C" >