admin管理员组文章数量:1406713
I have an Angular dropdown component (CustomDropdownComponent
) that receives a list of options and a selected value from its parent component via @Input()
. The parent also listens for selection changes using @Output()
.
However, I intentionally did not update the selectedValue
in the parent when handling the (selectionChange
) event to see if the dropdown would revert to the default selection. Surprisingly, the dropdown still updates to the newly selected option, even though the parent state remains unchanged.
My Questions:
- Why does the dropdown update the selected option even though the parent does not store the new value?
- Is this behavior due to Angular's change detection or how property bindings work?
- How can I ensure that the dropdown only displays what the parent provides and does not retain a selection unless explicitly stored in the parent?
Here is a simplified version of my implementation:
Parent Component (appponent.ts
)
export class AppComponent {
options = [
{ value: '1', text: 'Option 1' },
{ value: '2', text: 'Option 2' },
{ value: '3', text: 'Option 3' }
];
selectedValue = ''; // Intentionally not updating this when selection changes
handleOnChange(event: any) {
console.log(event.target.value); // Logging the value but not saving it
}
}
Parent Component Template (appponent.html
)
<app-custom-dropdown
[options]="options"
[selected]="selectedValue"
(selectionChange)="handleOnChange($event)">
</app-custom-dropdown>
Child Component (custom-dropdownponent.ts)
@Component({
selector: 'app-custom-dropdown',
templateUrl: './custom-dropdownponent.html',
styleUrls: ['./custom-dropdownponent.scss']
})
export class CustomDropdownComponent {
@Input() options: { value: string; text: string }[] = [];
@Input() selected: string = '';
@Output() selectionChange: EventEmitter<any> = new EventEmitter<any>();
onChange(event: any) {
this.selectionChange.emit(event); // Emitting value but parent does not save it
}
}
Child Component Template (custom-dropdownponent.html
)
<select (change)="onChange($event)" [value]="selected">
<option value="" hidden>default</option>
<option *ngFor="let option of options" [value]="option.value">
{{ option.text }}
</option>
</select>
I have an Angular dropdown component (CustomDropdownComponent
) that receives a list of options and a selected value from its parent component via @Input()
. The parent also listens for selection changes using @Output()
.
However, I intentionally did not update the selectedValue
in the parent when handling the (selectionChange
) event to see if the dropdown would revert to the default selection. Surprisingly, the dropdown still updates to the newly selected option, even though the parent state remains unchanged.
My Questions:
- Why does the dropdown update the selected option even though the parent does not store the new value?
- Is this behavior due to Angular's change detection or how property bindings work?
- How can I ensure that the dropdown only displays what the parent provides and does not retain a selection unless explicitly stored in the parent?
Here is a simplified version of my implementation:
Parent Component (appponent.ts
)
export class AppComponent {
options = [
{ value: '1', text: 'Option 1' },
{ value: '2', text: 'Option 2' },
{ value: '3', text: 'Option 3' }
];
selectedValue = ''; // Intentionally not updating this when selection changes
handleOnChange(event: any) {
console.log(event.target.value); // Logging the value but not saving it
}
}
Parent Component Template (appponent.html
)
<app-custom-dropdown
[options]="options"
[selected]="selectedValue"
(selectionChange)="handleOnChange($event)">
</app-custom-dropdown>
Child Component (custom-dropdownponent.ts)
@Component({
selector: 'app-custom-dropdown',
templateUrl: './custom-dropdownponent.html',
styleUrls: ['./custom-dropdownponent.scss']
})
export class CustomDropdownComponent {
@Input() options: { value: string; text: string }[] = [];
@Input() selected: string = '';
@Output() selectionChange: EventEmitter<any> = new EventEmitter<any>();
onChange(event: any) {
this.selectionChange.emit(event); // Emitting value but parent does not save it
}
}
Child Component Template (custom-dropdownponent.html
)
<select (change)="onChange($event)" [value]="selected">
<option value="" hidden>default</option>
<option *ngFor="let option of options" [value]="option.value">
{{ option.text }}
</option>
</select>
Share
edited Mar 4 at 13:34
Chait
1,3733 gold badges22 silver badges37 bronze badges
asked Mar 4 at 12:06
David KüngDavid Küng
294 bronze badges
1
- What you are describing is the expected <select> behaviour. It visually updates its selected option based on the user’s choice, even if the value binding does not explicitly update. – AnwarMEQOR Commented Mar 4 at 13:03
2 Answers
Reset to default 0My reasoning is this:
You have a property binding [value]="selected"
this means that only when the value selected
has an actual value change (1
-> 2
) will change detection run for the select and update the DOM, but in your scenario, you never update selected
value either in the child nor the parent, so there is no need for the view to update when the input value does not change.
If you check this below code, you will see, the HTML updated when I programatically set selectedValue
on the parent to 3
, but not on subsequent changes. Because the value goes from (''
--on first attempt--> 3
--on subsequent changes--> 3
(remains 3)) So the HTML never updates and keeps the user changes.
If you want to achieve a sort of revert, you have to do it programmatically.
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-custom-dropdown',
imports: [CommonModule, FormsModule],
template: `
<select [value]="selected" (change)="onChange($event)">
<option value="" hidden>default</option>
<option *ngFor="let option of options" [value]="option.value">
{{ option.text }}
</option>
</select>
`,
})
export class CustomDropdownComponent {
@Input() options: { value: string; text: string }[] = [];
@Input() selected: string = '';
@Output() selectionChange: EventEmitter<any> = new EventEmitter<any>();
onChange(event: any) {
this.selectionChange.emit(event); // Emitting value but parent does not save it
}
ngDoCheck() {
console.log('CustomDropdownComponent check');
}
}
@Component({
selector: 'app-root',
imports: [CustomDropdownComponent],
template: `
<app-custom-dropdown
[options]="options"
[selected]="selectedValue"
(selectionChange)="handleOnChange($event)">
</app-custom-dropdown>
`,
})
export class App {
options = [
{ value: '1', text: 'Option 1' },
{ value: '2', text: 'Option 2' },
{ value: '3', text: 'Option 3' },
];
ngDoCheck() {
console.log('App check');
}
selectedValue = ''; // Intentionally not updating this when selection changes
handleOnChange(event: any) {
this.selectedValue = '3';
console.log(event.target.value); // Logging the value but not saving it
}
}
bootstrapApplication(App);
Stackblitz Demo
Summary of the Issue & Solution
The reason my dropdown still displayed the selected option—even when I didn't store the selected value in the parent—was due to Angular's change detection optimizations. Since the selectedValue
in the parent never actually changed, Angular did not trigger a UI update, and the browser's native behavior retained the selected value.
To force Angular to reset the dropdown back to the default option, I had to explicitly introduce a temporary value change before resetting it back to ''
.
Working Solution
handleOnChange(event: any) {
console.log(event.target.value);
// Temporarily set a different value to force change detection
this.selectedValue = 'temp-value';
// Use setTimeout to reset it in the next JavaScript cycle
setTimeout(() => {
this.selectedValue = ''; // Revert to default selection
});
}
Using setTimeout() ensures that Angular detects both changes separately, allowing the dropdown to reset properly.
本文标签:
版权声明:本文标题:Why does my Angular dropdown update selection even when the parent does not store the selected value? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745044490a2639279.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论