Reputation: 11
I needed to emit a dropdown toggle value to a child component, but it won't get picked up by ngOnChanges detects when the dropdown toggle emits true, but doesn't detect when it emits false.
ChildComponent
export class ChildComponent implements OnInit, OnChanges, OnDestroy {
@Input() dropdownToggle!: boolean;
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['dropdownToggle']) {
const currentValue = changes['dropdownToggle'].currentValue;
console.log('ChildComponent ~ toggleDropdown value:', currentValue);
}
ParentComponent
export class ParentComponent implements OnInit, OnChanges {
@Output() dropdownToggle = new EventEmitter<boolean>();
showDropdown = false;
}
ngOnInit(): void {
@HostListener('document:click', ['$event']) checkExternalClick($event: Event) {
if (!this._elementRef.nativeElement.contains($event.target)) {
if (this.showDropdown) {
this.toggleDropdown();
}
} else {
this.showDropdown = true;
}
}
toggleDropdown() {
this.showDropdown = !this.showDropdown;
this.dropdownToggle.emit(this.showDropdown);
console.log('ParentComponent ~ toggleDropdown value:', this.showDropdown);
}
Made sure to properly bind event in the ParentComponent HTML:
<div class="dropdown-hover" *ngIf="showDropdown">
<div class="dropdown-value" (click)="toggleDropdown()">
<input class="select" [value]="selected" (focus)="toggleDropdown()" />
</div>
<div class="dropdown-content">
<hr class="divider" />
<app-child-component
[dropdownToggle]="showDropdown"
></app-child-component>
</div>
</div>
Result still the same:
Upvotes: 0
Views: 68
Reputation: 36351
The easier way to do this is by injecting the parent into the child component: constructor(protected parent: Parent)
. From there you can access the parent component's properties/functions.
This will be easier to maintain in the long run, as you don't need to manage 2+ variables that hold the same value(s).
The child would look something like this:
@Component({
selector: 'child',
standalone: true,
imports: [NgIf],
template: `
<div *ngIf="parent.showDropdown">
<p>Dropdown Open</p>
</div>
`,
})
export class Child {
constructor(protected parent: Parent) {}
}
The parent would then have the child
component within it's template or as a grandchild of another component.
@Component({
selector: 'parent',
standalone: true,
imports: [Child],
template: `
<div>
<child />
<button (click)="toggle()">Toggle</button>
</div>
`,
})
export class Parent {
showDropdown = false;
protected toggle() {
this.showDropdown = !this.showDropdown;
}
}
Upvotes: 0