Reputation: 27
I have this object selectedTask
2-way bound with [(ngModel)] to <ion-select>
tag. However, when the changes are made to the value of fields in selectedTask
, the Dom is not updated to reflect the change in value.
Here the html part:
<ion-label>Select Task</ion-label>
<ion-select [(ngModel)]="selectedTask" #A (ionChange)="updateChangedTask(false)">
<ion-option *ngFor="let task of tasklist" [value]="task">{{task.taskName}}</ion-option>
</ion-select>
</ion-item>
the .ts file:
constructor(private changeDetector: ChangeDetectorRef ...){ }
public selectedTask = {
taskName: "",
taskID: ""
};
...
changeTask(task: any){
this.selectedTask.taskName = task.taskName;
this.selectedTask.taskID = task.taskID;
this.changeDetector.detectChanges();
}
The value selected in the dropdown doesn't change when changeTask()
is called. I know the reason - because the reference of selectedTask
doesn't change and it is not detected by Angular by it as a change. How can I make it to detect the change in object field value?
Upvotes: 0
Views: 1313
Reputation: 14679
Don't mutate, create new object. Instead of
this.selectedTask.taskName = task.taskName;
this.selectedTask.taskID = task.taskID;
do for example
this.selectedTask = Object.assign({}, task);
Another take: use primitives (so, strings), instead of objects, for values.
<ion-select [(ngModel)]="selectedTask" #A (ionChange)="updateChangedTask(false)">
<ion-option *ngFor="let task of tasklist" [value]="task.taskID">{{task.taskName}}</ion-option>
</ion-select>
and in TS:
public selectedTask = "";
//...
changeTask(task: any) {
this.selectedTask = task.taskID;
this.changeDetector.detectChanges(); // may be unnecessary
}
Upvotes: 0
Reputation: 42516
I realise you have binded an object to the value
attribute. This is incorrect, as the value attribute only accepts numbers or strings.
However, if you want to bind an object to ion-option, you should use bind the task
property to ngValue
instead
<ion-label>Select Task</ion-label>
<ion-select [(ngModel)]="selectedTask" #A (ionChange)="updateChangedTask(false)">
<ion-option *ngFor="let task of tasklist" [ngValue]="task">{{task.taskName}}</ion-option>
</ion-select>
</ion-item>
If you would prefer to bind a string/number instead of an entire object, you will need to make the following changes to both your component.html, and component.ts
First, you bind selectedTask
to the taskID
string
public selectedTask: string = '';
changeTask(task: any){
this.selectedTask = task.taskID;
}
And then, you bind the value
attribute of ion-options to task.taskID
which holds a string value.
<ion-label>Select Task</ion-label>
<ion-select [(ngModel)]="selectedTask" #A (ionChange)="updateChangedTask(false)">
<ion-option *ngFor="let task of tasklist" [value]="task.taskID">{{task.taskName}}</ion-option>
</ion-select>
</ion-item>
You can choose to adopt either methods, and 2-way data binding should work accordingly.
Upvotes: 1