📜  Angular PrimeNG 就地组件(1)

📅  最后修改于: 2023-12-03 14:39:13.363000             🧑  作者: Mango

Angular PrimeNG 就地组件

Angular PrimeNG 是基于 Angular 框架的 UI 库,提供了丰富的组件和样式,支持响应式和可定制性,使开发者能够快速创建现代化的 Web 应用程序。

其中之一的就地组件,主要用于在表格中进行编辑,允许用户在单元格内直接编辑数据,而无需打开编辑表单。在本文中,我们将探讨如何使用 Angular PrimeNG 就地组件。

安装

在使用 Angular PrimeNG 就地组件之前,我们需要先安装以下软件包:

  • Angular
  • PrimeNG
  • Font Awesome
  • @angular/cdk
npm install angular primeng font-awesome @angular/cdk --save
导入模块

在 app.module.ts 文件中,导入以下模块:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TableModule } from 'primeng/table';
import { InputTextModule } from 'primeng/inputtext';
import { ButtonModule } from 'primeng/button';
import { InputTextareaModule } from 'primeng/inputtextarea';
import { DialogModule } from 'primeng/dialog';
import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    TableModule,
    InputTextModule,
    ButtonModule,
    InputTextareaModule,
    DialogModule,
    FormsModule,
    ReactiveFormsModule,
    HttpClientModule,
    AppRoutingModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
创建组件

创建一个名为 EmployeesComponent 的组件,并在模板中添加一个名为 employees 的 PrimeNG 表格组件,设置列和数据以及一个 editEmployeeDialog 对话框组件。

import { Component, OnInit, ViewChild } from '@angular/core';
import { Employee } from '../models/employee.model';
import { EmployeeService } from '../services/employee.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ConfirmationService, MessageService } from 'primeng/api';
import { Table } from 'primeng/table';

@Component({
  selector: 'app-employees',
  templateUrl: './employees.component.html',
  styleUrls: ['./employees.component.scss'],
  providers: [ConfirmationService, MessageService],
})
export class EmployeesComponent implements OnInit {
  employees: Employee[];
  employeeDialog: boolean;
  submitted: boolean = false;
  employeeForm: FormGroup;
  selectedEmployee: Employee;
  editEmployeeDialog: boolean;
  @ViewChild('employeeTable') table: Table;

  constructor(
    private employeeService: EmployeeService,
    private fb: FormBuilder,
    private confirmationService: ConfirmationService,
    private messageService: MessageService
  ) {}

  ngOnInit() {
    this.employeeForm = this.fb.group({
      id: [],
      name: ['', Validators.required],
      designation: ['', Validators.required],
      expertise: ['', Validators.required],
      country: ['', Validators.required],
    });

    this.employeeService.getEmployees().then((employees: Employee[]) => {
      this.employees = employees.map((employee) => ({
        ...employee,
        country: employee.country.name,
      }));
    });
  }

  openNew() {
    this.employeeForm.reset();
    this.submitted = false;
    this.employeeDialog = true;
  }

  editEmployee(employee: Employee) {
    this.employeeForm.patchValue({ ...employee });
    this.editEmployeeDialog = true;
  }

  hideDialog() {
    this.employeeDialog = false;
    this.editEmployeeDialog = false;
    this.submitted = false;
  }

  saveEmployee() {
    this.submitted = true;

    if (this.employeeForm.invalid) return;

    const employeeIndex = this.employees.findIndex(
      (employee) => employee.id === this.employeeForm.value.id
    );

    if (employeeIndex !== -1) {
      this.employees[employeeIndex] = { ...this.employeeForm.value };
    } else {
      this.employees = [...this.employees, { ...this.employeeForm.value }];
    }

    this.messageService.add({
      severity: 'success',
      summary: 'Successful',
      detail: 'Employee Created',
      life: 3000,
    });

    this.hideDialog();
  }

  deleteEmployee(rowData) {
    this.confirmationService.confirm({
      message: 'Are you sure you want to delete ' + rowData.name + '?',
      header: 'Confirm',
      icon: 'pi pi-exclamation-triangle',
      accept: () => {
        this.employees = this.employees.filter(
          (employee) => employee.id !== rowData.id
        );

        this.messageService.add({
          severity: 'success',
          summary: 'Successful',
          detail: 'Employee Deleted',
          life: 3000,
        });
      },
    });
  }

  onRowEditInit(employee: Employee) {
    this.selectedEmployee = { ...employee };
  }

  onRowEditSave(employee: Employee) {
    const employeeIndex = this.employees.findIndex(
      (data) => data.id === employee.id
    );
    this.employees[employeeIndex] = { ...employee };
    this.messageService.add({
      severity: 'success',
      summary: 'Successful',
      detail: 'Employee Updated',
      life: 3000,
    });
  }

  onRowEditCancel(employee: Employee, index: number) {
    this.employees[index] = this.selectedEmployee;
    this.messageService.add({
      severity: 'info',
      summary: 'Canceled',
      detail: 'Employee Update Canceled',
      life: 3000,
    });
  }
}
编辑单元格

要在 PrimeNG 表格中使用就地编辑,我们需要在表格列定义中为需要编辑的列指定 editable 属性,为列指定 PrimeNG 就地组件。

<div class="p-col-12">
  <p-table #employeeTable [value]="employees" rowHover="true" [paginator]="true" [rows]="10" [responsive]="true">
    <ng-template pTemplate="caption">
      <div style="display:flex;justify-content:space-between;align-items:center;">
        <h4>Employees List</h4>
        <button pButton icon="pi pi-plus" label="Add Employee" (click)="openNew()"></button>
      </div>
    </ng-template>
    <ng-template pTemplate="header">
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Designation</th>
        <th>Expertise</th>
        <th>Country</th>
        <th>Actions</th>
      </tr>
    </ng-template>
    <ng-template pTemplate="body" let-employee let-rowIndex="rowIndex" let-editing="editing">
      <tr [pRowToggler]="employee" class="employee-row" [pSelectableRow]="employee">
        <td>{{ employee.id }}</td>
        <td>
          <p-cellEditor>
            <ng-template pTemplate="output">{{ employee.name }}</ng-template>
            <ng-template pTemplate="input">
              <input pInputText [(ngModel)]="employee.name" />
            </ng-template>
          </p-cellEditor>
        </td>
        <td>
          <p-cellEditor>
            <ng-template pTemplate="output">{{ employee.designation }}</ng-template>
            <ng-template pTemplate="input">
              <input pInputText [(ngModel)]="employee.designation" />
            </ng-template>
          </p-cellEditor>
        </td>
        <td>
          <p-cellEditor>
            <ng-template pTemplate="output">{{ employee.expertise }}</ng-template>
            <ng-template pTemplate="input">
              <input pInputText [(ngModel)]="employee.expertise" />
            </ng-template>
          </p-cellEditor>
        </td>
        <td>
          <p-cellEditor>
            <ng-template pTemplate="output">{{ employee.country }}</ng-template>
            <ng-template pTemplate="input">
              <p-dropdown
                [options]="countries"
                [(ngModel)]="employee.country"
                optionLabel="name"
                [style]="{ width: '100%' }"
              ></p-dropdown>
            </ng-template>
          </p-cellEditor>
        </td>
        <td class="text-center">
          <button
            pButton
            type="button"
            icon="pi pi-pencil"
            class="p-button-rounded p-button-success"
            (click)="editEmployee(employee)"
          ></button>
          <button
            pButton
            type="button"
            icon="pi pi-trash"
            class="p-button-rounded p-button-danger"
            (click)="deleteEmployee(employee)"
          ></button>
        </td>
      </tr>
    </ng-template>
    <ng-template pTemplate="rowexpansion" let-employee let-rowIndex="rowIndex">
      <div class="p-grid" [style]="{ padding: '2em' }">
        <div class="p-col-12 p-md-3">
          <strong>ID:</strong>
        </div>
        <div class="p-col-12 p-md-9">
          {{ employee.id }}
        </div>

        <div class="p-col-12 p-md-3">
          <strong>Name:</strong>
        </div>
        <div class="p-col-12 p-md-9">
          {{ employee.name }}
        </div>

        <div class="p-col-12 p-md-3">
          <strong>Designation:</strong>
        </div>
        <div class="p-col-12 p-md-9">
          {{ employee.designation }}
        </div>

        <div class="p-col-12 p-md-3">
          <strong>Expertise:</strong>
        </div>
        <div class="p-col-12 p-md-9">
          {{ employee.expertise }}
        </div>

        <div class="p-col-12 p-md-3">
          <strong>Country:</strong>
        </div>
        <div class="p-col-12 p-md-9">
          {{ employee.country }}
        </div>
      </div>
    </ng-template>
  </p-table>
</div>

在上面的代码中,我们为每个需要编辑的列指定 editable 属性,并将其包装在 p-cellEditor 中。每个 ng-template 中的内容表示单元格处于不同状态(输出或输入)时应显示的内容。在输出状态下,单元格仅显示数据。在输入状态下,单元格中将显示允许用户编辑数据的控件。

总结

Angular PrimeNG 就地组件可以使我们在表格中直接编辑数据,而无需打开编辑表单,从而提高了用户体验。在本文中,我们学习了如何在 Angular PrimeNG 表格中使用就地组件,并配置了 Angular PrimeNG 整个应用程序所需的软件包和模块。