SBB
SBB

Reputation: 8970

Angular - 2 way data binding multiple values

Forgive the title, I am not entirely sure of what I am trying to ask here.

I have an html table and using *ngFor to iterate over a data object. Within this iteration, I print out the value of a specific field and attached an *ngIf to it. When my table is in "Edit Mode" that text value goes away and a dropdown menu is expose to allow the user to change the value.

The dropdown uses ngModel and I can see my data being updated correctly within my json that I have right below my dropdown. My issue however is that this dropdown is bound to the OperatorID in my object (which is correct) but the Text in the dropdown is a different part of the object.

HTML:

<td class="small col-md-1 oper">
  <span *ngIf="!inEditMode(r.RuleParentID, a.AttributeID)">
   <strong>{{ a.OperatorName }}</strong>
  </span>
  <select class="form-control input-sm" [(ngModel)]="a.OperatorID" *ngIf="inEditMode(r.RuleParentID, a.AttributeID)">
    <option *ngFor="let o of fetchOperatorList(a.AttributeID)" [value]="o.OperatorID" [selected]="o.OperatorID === a.OperatorID">{{ o.OperatorName }}</option>
  </select>
</td>

Data Object:

{
    "AttributeID": "2",
    "AttributeName": "Role",
    "OperatorID": "3",
    "OperatorName": "In List",
    "SqlOperator": "IN"
}

The issue I am facing is that once I change the value in the dropdown and it updates the OperatorID in my object, I then disable "Edit Mode" which turns the dropdown back into the interpolated text it printed from the *ngFor, which is OperatorName in the object.

This results in the name not getting updated and the value is getting updated.

Is there a way to bind on multiple values? When I select an option in my select for example, I want the select value to update OperatorID and the select text to update the OperatorName.

How should I approach this?

Upvotes: 0

Views: 8871

Answers (2)

bgraham
bgraham

Reputation: 1997

Instead of using ngModel, you can use a function in the component and bind it to the change event of the select.

Template:

        <div>{{selectedOperator | json}}</div>
        <select class="form-control input-sm" #mySelect     
          (change)="onSelectChange(mySelect.value)">
          <option *ngFor="let o of operators" 
          [value]="o.OperatorID" [selected]="o.OperatorID ===     selectedOperator.OperatorID">{{ o.OperatorName }}</option>
        </select>

Component:

  selectedOperator;

    operators = [
      {
        OperatorID: 1,
        OperatorName: "Foo"
      },
      {
        OperatorID: 2,
        OperatorName: "Bar"
      },
      {
        OperatorID: 3,
        OperatorName: "Awesomesauce"
      }
    ]

    onSelectChange(id) {

      this.selectedOperator = this.operators.find(i => i.OperatorID === Number(id));


    }

    ngOnInit(){
      this.selectedOperator = this.operators[2];
  }

Plunker: https://plnkr.co/edit/G0N7xvVDJEokDEwnMsvS

Upvotes: 1

Daniel Orme&#241;o
Daniel Orme&#241;o

Reputation: 2778

If i understood your problem correctly, You need to update the a.OperatorName to whatever it corresponds to the new selection (Based on the id). You should be able to achieve this by binding to the select change event.

<select class="form-control input-sm"
        [(ngModel)]="a.OperatorID"
        *ngIf="inEditMode(r.RuleParentID, a.AttributeID)"
        (change)="onChange($event.target.value)">
    <option *ngFor="let o of fetchOperatorList(a.AttributeID)" [value]="o.OperatorID" [selected]="o.OperatorID === a.OperatorID">{{ o.OperatorName }}</option>
</select>

Then in your component.

public onChange(operatorId) {
    // update operator object in collection based on id 
}

Upvotes: 3

Related Questions