I am working on an Angular application using PrimeNG and I have the following problem.
I had a component containing a PrimeNG Dialog defined inside (this one: https://www.primefaces.org/primeng/showcase/#/dialog ) and it works fine.
To keep neat my code I decided to refactor it and I created a sub component containing only the PrimeNG dialog. So basically now I have something like this:
PARENT COMPONENT HTML::
<app-employee-add-form [displayNewEmployeeDialog]="displayNewEmployeeDialog"></app-employee-add-form>
<div class="container">
<!-- TOOLBAR -->
<div class="card" id="toolbar-card">
<div class="toolbar-container">
<div class="row">
<div id="toolbar-left" class="col-6 d-flex justify-content-start">
<button pButton pRipple label="New" icon="pi pi-plus"
class="p-button-success p-mr-2"
(click)="showNewEmployeeDialog()">
</button>
<button pButton pRipple icon="pi pi-trash" class="p-button-danger"></button>
</div>
<div id="toolbar-right" class="col-6 d-flex justify-content-end">
<!--<p-fileUpload mode="basic" accept="image/*" [maxFileSize]="1000000" label="Import" chooseLabel="Import" class="p-mr-2 p-d-inline-block"></p-fileUpload>-->
<button type="button" pButton pRipple label="Export" icon="pi pi-file-excel"
class="p-button-success p-mr-2"
pTooltip="XLS" tooltipPosition="bottom"></button>
</div>
</div>
</div>
</div>
So basically the first line:
<app-employee-add-form [displayNewEmployeeDialog]="displayNewEmployeeDialog"></app-employee-add-form>
Then I defined a New button that will call a method in order to show the dialog defined into the child component.
define the child component that will show the modal that bind the displayNewEmployeeDialog parent component to the displayNewEmployeeDialog of the child modal component in order to show or not show the modal in the parent component page.
This is the related TypeScript code of my parent component:
@Component({
selector: 'app-employee-list',
templateUrl: './employee-list.component.html',
styleUrls: ['./employee-list.component.scss']
})
export class EmployeeListComponent implements OnInit {
displayNewEmployeeDialog = false;
customers: Customer[];
selectedCustomers: Customer[];
representatives: Representative[];
statuses: any[];
loading: boolean = true;
@ViewChild('dt') table: Table;
constructor(private customerService: CustomerService, private primengConfig: PrimeNGConfig) { }
ngOnInit() {
this.customerService.getCustomersLarge().then(customers => {
this.customers = customers;
this.loading = false;
});
this.representatives = [
{name: "Amy Elsner", image: 'amyelsner.png'},
{name: "Anna Fali", image: 'annafali.png'},
{name: "Asiya Javayant", image: 'asiyajavayant.png'},
{name: "Bernardo Dominic", image: 'bernardodominic.png'},
{name: "Elwin Sharvill", image: 'elwinsharvill.png'},
{name: "Ioni Bowcher", image: 'ionibowcher.png'},
{name: "Ivan Magalhaes",image: 'ivanmagalhaes.png'},
{name: "Onyama Limba", image: 'onyamalimba.png'},
{name: "Stephen Shaw", image: 'stephenshaw.png'},
{name: "XuXue Feng", image: 'xuxuefeng.png'}
];
this.statuses = [
{label: 'Unqualified', value: 'unqualified'},
{label: 'Qualified', value: 'qualified'},
{label: 'New', value: 'new'},
{label: 'Negotiation', value: 'negotiation'},
{label: 'Renewal', value: 'renewal'},
{label: 'Proposal', value: 'proposal'}
]
this.primengConfig.ripple = true;
}
onActivityChange(event) {
const value = event.target.value;
if (value && value.trim().length) {
const activity = parseInt(value);
if (!isNaN(activity)) {
this.table.filter(activity, 'activity', 'gte');
}
}
}
onDateSelect(value) {
this.table.filter(this.formatDate(value), 'date', 'equals')
}
formatDate(date) {
let month = date.getMonth() + 1;
let day = date.getDate();
if (month < 10) {
month = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
return date.getFullYear() + '-' + month + '-' + day;
}
onRepresentativeChange(event) {
this.table.filter(event.value, 'representative', 'in')
}
showNewEmployeeDialog() {
console.log("showNewEmployeeDialog() START !!!");
this.displayNewEmployeeDialog = true;
}
}
Basically the only thing that are related to my problem are this line that define the displayNewEmployeeDialog as false in order to avoid to show the dialog child component when I load the page of this parent component:
displayNewEmployeeDialog = false;
and this method that change the value of this variable in order to open my dialog when the user click on the New button:
showNewEmployeeDialog() {
console.log("showNewEmployeeDialog() START !!!");
this.displayNewEmployeeDialog = true;
}
Then this is the view code of my child component:
<p-dialog header="Inserire un nuovo impiegato"
maximizable="true"
[(visible)]="displayNewEmployeeDialog"
position="top"
[style]="{width: '50vw'}">
<form [formGroup]="newEmployeeForm" id="addEmployeeForm">
<div class="row">
<div class="col-2">
<p>Nome</p>
</div>
<div class="col-10">
<input id="name" formControlName="name" type="text" pInputText />
</div>
</div>
</form>
<p-footer>
<span class="p-buttonset">
<button pButton type="button" label="Save" icon="pi pi-check"></button>
<button pButton type="button" label="Cancel" icon="pi pi-times" (click)="closeDialog()"></button>
</span>
</p-footer>
</p-dialog>
At the moment it contains a minimalistic form. It is set to visible when the displayNewEmployeeDialog value is set to true, otherwise it will be invisible.
And this is the TypeScript code of this child component:
@Component({
selector: 'app-employee-add-form',
templateUrl: './employee-add-form.component.html',
styleUrls: ['./employee-add-form.component.scss']
})
export class EmployeeAddFormComponent implements OnInit {
@Input()
displayNewEmployeeDialog: boolean;
newEmployeeForm: FormGroup;
constructor() { }
ngOnInit(): void {
console.log("bla");
}
closeDialog() {
this.displayNewEmployeeDialog = false;
this.ngOnInit();
}
}
As you can see I am simply importing the displayNewEmployeeDialog value from the parent using the @Input() decoreator in order to detact changes and open and close my modal.
The problem is that when I click for the first time my "Add" button into the parent component my modal will be correctly opened as shown here:
The problem is that closing this modal clicking on the upper right X icon or on the "Cancel" button if I try to open a new modal (clicking again on the "Add" button of the parent component) the modal doesn't appear. I have no error in the console.
Why this behavior? Clicking on the "Add" button of the parent component the value should be received by the child component as "true" so the modal should be show again but it is not happening? What am I missing? How can I fix this issue?