Reputation: 8970
I have a very simple, or so I thought, select input. It is getting its values for the option
tags by using ngFor
. I also am using [selected]
to set the value of the input based on what the user has selected.
The Behavior:
When I click on the dropdown, it is flashing like it is loading or doing something twice. It doesn't have the normal opening event like I remember seeing. Once it is open, I can pick a value just fine. If I go back and re-open the options again, it is setting the selected option back to what is currently selected in the object. <--- This may be normal behavior since I am telling it what selected
should be. Ideally though, this should be set one time and then not reset each time it is opened.
HTML:
<select class="form-control input-sm" *ngIf="inEditMode(r.RuleParentID, a.AttributeID)" (change)="updateOperator($event)">
<option value="">Select Operator</option>
<option *ngFor="let o of fetchOperatorList(a.AttributeID)" [value]="o.OperatorID" [selected]="o.OperatorID === a.OperatorID">{{ o.OperatorName }}</option>
</select>
fetchOperatorList() method:
fetchOperatorList(attributeID) {
let temp = Array();
// Scan our attributes
for (const key in this.globalMapData.attributes) {
// Find attribute by property
if (this.globalMapData.attributes.hasOwnProperty(key)) {
// If this attribute is the one we are searching, continue
if (this.globalMapData.attributes[key].AttributeID == attributeID) {
// Loop over the operators for this attribute
let ops = this.globalMapData.attributes[key].attributeOperators.a;
for (var i = 0; i < ops.length; i++) {
// Push possible attribute operators to an array
temp.push({
OperatorID: ops[i].OperatorID,
OperatorName: ops[i].OperatorName,
SqlOperator: ops[i].SqlOperator
});
}
}
}
}
return temp;
}
Example Image:
Goal:
First, I have no idea why it is doing the whole appearance of double loading, seems off...
Is there also a way to set the default selected value but not reset it back every time the input is opened? To get to this point, the user clicked "Edit" on the page and was provided the select
to change the option. If they happen to pick the wrong thing and open it again, I don't want it to reset back to the original.
Update:
I removed the ngIf
on the select itself as well as the onChange
to help narrow it down. The issue still occurs. I removed the selected
property and only kept [value]
. I put in a console.log
in the ngFor
function and thats where it was interesting. It appears to be running two times, multiple times. I am going to look at this function a little more and see what is being output but that's gotta be part of the problem.
Update2:
This select is wrapped within another ngFor
that is looping over all of my user records. What appears to be happening is when the ngIf
becomes true, it calls the ngFor
on the select options
for the number of times it was iterated over.
<tr class="attribute" *ngFor="let a of r.attributes.attribute" [class.info]="inEditMode(r.RuleParentID, a.AttributeID)">
<td class="small col-md-2 attr"><strong>{{ a.AttributeName }}</strong></td>
<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" *ngIf="inEditMode(r.RuleParentID, a.AttributeID)">
<option value="">Select Operator</option>
<option *ngFor="let o of fetchOperatorList(a.AttributeID)" [value]="o.OperatorID">{{ o.OperatorName }}</option>
</select>
</td>
</tr>
Upvotes: 0
Views: 800
Reputation: 14257
Sometimes this happens in development mode, it's because angular's changedetection is running twice for each change. This is likely causing the flash, because you're creating a new reference of the array and the ngForOf
directive is reflecting that. You could try to tell the ngForOf
directive to track it's children by index without taking the reference into account via trackBy
and a function.
trackByIndex(index: number, value: any) {
return index;
}
And inside your template:
*ngFor="...;trackBy:trackByIndex"
Upvotes: 1