Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to bind input to two variables at the same time in Angular?

This is a typical Angular's Material matInput:

<input matInput [(ngModel)]="model.property" name="property" />

Now to apply logic when the model changes, a common solution proposed by other developers in SO is to break banana-in-the-box into property-binder and event-hook expressions:

<input matInput [ngModel]="model.property" (ngModelChange)="model.property=someLogic($event)" />

Based on this logic, I created a digitGroup function that gets the input number, puts commas in between each three numbers, and shows that in the matInput field.

However, the problem is that now the model.property is a string representing the digit-grouped number, rather than being a real JavaScript number, so in each place I need to access its value and do some mathematical operation on it, I need to undigitGroup(model.property) first.

Is it possible that I bind matInput to two properties of the model at the same time? That way I can have model.property for calculations and model.digitGroupedProperty to show to the user, both at the same time.

like image 756
mohammad rostami siahgeli Avatar asked May 21 '18 07:05

mohammad rostami siahgeli


People also ask

Is there two way data binding in Angular?

The two-way data binding in Angular enables data to flow from the component to the view and the other way round. It is used to display information to the end-user and allows them to make changes to the underlying data using the UI.

Can ngModel have multiple values?

The solution is ng-bind-template, it can bind more than one {{}} expression, so it can show more than a single value that was declared in the Script function.

Which is the syntax for two way binding in Angular?

[()] = [] + () where [] binds attribute, and () binds an event. The [(ngModel)] syntax is the recommended way of two-way data binding. The ngModel directive with [] syntax is used for one-way data binding. [ngModel] binds a value to a property to UI control.

What is ngModel two way binding?

Two way data binding means that changes made to our model in the component are propagated to the view and that any changes made in the view are immediately updated in the underlying component data. Two way data binding is useful in data entry forms.


2 Answers

You can use pipes to display the model transformed by digitGroup function without changing the model.

@Pipe({name: 'groupDigits'})
export class DigitGroupPipe implements PipeTransform {
  transform(value: any) {
      // Call your digitGroup() function here, then return result
  }
}

Then use them like this:

<input matInput [ngModel]="model.property | groupDigits" (ngModelChange)="model.property=$event" />

That way, your model will not be mutated by your digitGroup() function, only on the view

like image 79
Jed Cua Avatar answered Oct 31 '22 16:10

Jed Cua


As Jed Cua said, you should be able to do it with pipe. But you can also do it manually with a local variable, having the local variable for user display and model property for calculations.

  1. In your component, init a local variable modelPropertyRaw modelPropertyRaw = digitGroup(model.property) in ngOnInit
  2. Bind input to local variable modelPropertyRaw
  3. Add (input)="onPropertyChange($event.target.value)" to your input
  4. In onPropertyChange, do model.property = undigitGroup(modelPropertyRaw)

This separate true value from shown value.


EDIT: In your .html file

<!-- Replaced (ngOnModelChange) by (input). Notice that you are not forced to pass the event for the behavior we want -->
<input matInput [ngModel]="modelPropertyRaw" (input)="onPropertyChange($event.target.value)" />

In your .ts file

Add a local variable modelPropertyRaw (you can also add it as an attribute of your model class)

modelPropertyRaw: string;

Add onPropertyChange function like this

onPropertyChange(inputText: string)
{
  model.property = undigitGroup(modelPropertyRaw);
}

That's it ! If you don't want component local variable, add propertyRaw as an attribute of model and use it instead of modelPropertyRaw in this code

like image 28
Sebastien Servouze Avatar answered Oct 31 '22 16:10

Sebastien Servouze