为什么在我关闭定义到子组件中的 PrimeNG 模态之后我无法再次打开它?

Why after that I close a PrimeNG modal defined into a child component I can't open it again?

我正在使用 PrimeNG 开发 Angular 应用程序,但遇到以下问题。

我有一个包含内部定义的 PrimeNG 对话框的组件(这个:https://www.primefaces.org/primeng/showcase/#/dialog)并且工作正常。

为了保持我的代码整洁,我决定重构它并创建了一个仅包含 PrimeNG 对话框的子组件。所以基本上现在我有这样的东西:

父组件 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>

第一行基本上是:

<app-employee-add-form [displayNewEmployeeDialog]="displayNewEmployeeDialog"></app-employee-add-form>

然后我定义了一个 New 按钮,它将调用一个方法来显示子组件中定义的对话框。

定义将显示模态的子组件,按顺序将 displayNewEmployeeDialog 父组件绑定到子模态组件的 displayNewEmployeeDialog在父组件页面显示或不显示模态。

这是我父组件的相关TypeScript代码:

@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;
    }
}

基本上唯一与我的问题相关的是将 displayNewEmployeeDialog 定义为 false 的这一行,以避免在我加载页面时显示对话框子组件此父组件:

displayNewEmployeeDialog = false;

这个方法改变了这个变量的值,以便在用户单击 New 按钮时打开我的对话框:

showNewEmployeeDialog() {
    console.log("showNewEmployeeDialog() START !!!");
    this.displayNewEmployeeDialog = true;
}

那么这是我的子组件的视图代码:

<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>

目前它包含一个简约的形式。 displayNewEmployeeDialog值设置为true时设置为可见,否则不可见。

这是这个子组件的 TypeScript 代码:

@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();
  }

}

如您所见,我只是使用 @Input() 装饰器从父级导入 displayNewEmployeeDialog 值,以便删除更改并打开和关闭我的模式。

问题是,当我第一次点击父组件中的“添加”按钮时,我的模式将正确打开,如下所示:

问题是,如果我尝试打开一个新的模态(再次点击父组件的“添加”按钮),点击右上角的 X 图标或“取消”按钮关闭这个模态没有出现。我在控制台没有错误。

为什么会出现这种行为?单击父组件的“添加”按钮,子组件应将值接收为“true”,因此模态应再次显示,但它没有发生?我错过了什么?我该如何解决这个问题?

您需要定义两个属性,一个输入 属性 和一个输出 属性 以发出关闭事件。 displayNewEmployeeDialog 属性 应仅由父组件控制:

child.component.ts

export class EmployeeAddFormComponent implements OnInit {

  @Input()
  displayNewEmployeeDialog: boolean;
  @Output
  onDialogClose: EventEmitter<any> = new EventEmitter(); 

  //.. 

  closeDialog() {
    this.onDialogClose.emit();
  }

}

parent.component.html

<app-employee-add-form [displayNewEmployeeDialog]="displayNewEmployeeDialog" (onDialogClose)="closeDialog()"></app-employee-add-form>

parent.component.ts

closeDialog(): void {
  this.displayNewEmployeeDialog=false;
}