Reputation: 3506
I'm trying to set the CSS class within 'EditDialogComponent' below (which is a modal view), depending on an input property called 'showMe' that is set from 'AppComponent':
<div [ngClass]="showMe? 'ui active modal': 'ui modal'">
<i class="close icon"></i>
<div class="header">
Edit
</div>
<div class="actions">
<div (click)="cancel()" class="ui black deny button">
Cancel
</div>
<div class="ui positive right labeled icon button">
OK
<i class="checkmark icon"></i>
</div>
</div>
</div>
2. TypeScript Code:
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
@Component({
selector: 'edit-dialog',
templateUrl: './edit-dialog.component.html',
styleUrls: ['./edit-dialog.component.css']
})
export class EditDialogComponent implements OnInit {
_showMe: boolean
@Input() subject: string
@Input() set showMe(value: boolean) {
this._showMe = value
window.alert('Trying to show modal')
}
get showMe() : boolean {
return this._showMe
}
cancel() {
this._showMe = false
}
constructor() { }
ngOnInit() {
}
}
Below is the code used to include 'EditDialogComponent' into 'AppComponent':
<button (click)='edit()'>Edit</button>
<edit-dialog [showMe]="show_edit_modal" subject='foobar'></edit-dialog>
edit() {
window.alert('Trying to show modal')
this.show_edit_modal = true }
The problem is after the showMe
@Input() gets changed from within EditDialogComponent
(invoked by the click on the 'Cancel' button of the modal), it fails to detect the change of the data binding (i.e show_edit_modal) that is invoked by AppComponent.edit()
(that displays "Trying to show modal" whenever I click on the Edit button of AppComponent)), since the alert from EditDialogComponent.ngOnChanges()
stops showing.
Why changing the @Input variable from within the internal component causes its failure to detect new changes from external component?
Upvotes: 3
Views: 2078
Reputation: 3348
@Input
is just a one way binding. If you want to also change values in the parent component you have to create a two ways data binding. In order to do that you have to create an output with the same name of your input (showMe
in your case) + Change (eg: showMeChange: EventEmitter<any>
), and emit in your showMe setter.
In your parent component now you can use this like ngModel
.
<edit-dialog [(showMe)]="show_edit_modal" subject='foobar'></edit-dialog>
I've created a full example here: https://stackblitz.com/edit/angular-c83djz
Upvotes: 2
Reputation: 657048
This is working as intended. @Input()
doesn't cause changes to be detected.
showMe="{{show_edit_modal}}"
is what Angulars change detection checks.
Ir better
[showMe]="show_edit_modal"
to actually pass a boolean value instead of a string
What you can do is to make showMe
a setter
_showMe:boolean;
@Input() set showMe(val: boolean) {
this._showMe = val;
window.alert('Trying to show modal')
}
get showMe() : boolean {
return this._showMe;
}
Upvotes: 1