如何修复 Angular 中的此错误并将数据输出到 PDF?

Posted

技术标签:

【中文标题】如何修复 Angular 中的此错误并将数据输出到 PDF?【英文标题】:How can I fix this error in Angular and output data to a PDF? 【发布时间】:2021-11-24 09:00:49 【问题描述】:

我正在尝试使用模式中的按钮将数据输出到 PDF,该按钮也显示相同的数据。我在模态中显示的数据没有问题,但我正在尝试创建一个选项以将结果下载到 PDF。我一直在学习教程,但目前在加载我的 Web 应用程序时在控制台中收到错误

core.js:6479 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[MatDialogRef -> MatDialogRef -> MatDialogRef]: 
  NullInjectorError: No provider for MatDialogRef!
NullInjectorError: R3InjectorError(AppModule)[MatDialogRef -> MatDialogRef -> MatDialogRef]: 
  NullInjectorError: No provider for MatDialogRef!

我有一个单独的组件,仅用于保存模式的数据和标记,因此我也在尝试在我的 auth-layout.component.ts 中实现 PDF 选项的功能

这是我的 auth.component.html

<h2 mat-dialog-title>Order Summary</h2>
<div mat-dialog-content id="output" id="output">
  <div>
    <strong>Menu items:</strong>
    <tr *ngFor="let item of invoice.serviceItems">
      &nbsp; item.serviceName  (item.servicePrice | currency)
    </tr>
    <br /> Subtotal:  invoice.getTotal() | currency 
  </div>
  <hr />
  <p>
    Labor Cost:  invoice.getLaborTotal() | currency 
  </p>
  <hr />
  <p style="font-weight: bold;">Invoice total:  invoice.getInvoice() | currency </p>
</div>
<div mat-dialog-actions align="end">
  <button mat-raised-button matDialogClose="cancel" color="primary">Cancel order</button>
  <button mat-raised-button matDialogClose="confirm" color="accent" (click)="openPDF()">Confirm order</button>
</div>

这里是 auth-layout.component.ts

import  MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule from '@angular/material/dialog';
import  Component, OnInit, Input, ElementRef, ViewChild, Inject  from '@angular/core';
import  Invoice  from '../invoice';

import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';

@Component(
  selector: 'app-auth-layout',
  templateUrl: './auth-layout.component.html',
  styleUrls: ['./auth-layout.component.css']
)
export class AuthLayoutComponent implements OnInit 

  invoice: Invoice;
  @ViewChild("output", 
    static: true
  ) output: ElementRef;


  constructor(private dialogRef: MatDialogRef < AuthLayoutComponent > , @Inject(MAT_DIALOG_DATA) data: any) 
    this.invoice = data.invoice;
    console.log(this.invoice);
  

  openPDF() 
    const data = this.output.nativeElement;
    const doc: jsPDF = new jsPDF("p", "mm", "a4");
    doc.html(data, 
      callback: (doc) => 
        doc.output("dataurlnewwindow");
      
    );
  

  ngOnInit(): void 

我的 services.component.ts 也是,我实际上在其中打开了模式

import  Observable  from 'rxjs';
import  MatDialog, MatDialogRef, MAT_DIALOG_DATA from '@angular/material/dialog';
import  ServiceHelper  from '../services.service';
import  ServiceItem  from '../services.interface';
import MatCheckboxModule from '@angular/material/checkbox';
import FormBuilder, FormGroup, FormArray, FormControl  from '@angular/forms';
import MatSnackBar from '@angular/material/snack-bar';
import  FormsModule  from '@angular/forms';
import  Invoice  from '../invoice';
import  AuthLayoutComponent  from './../auth-layout/auth-layout.component';
import  jsPDF  from "jspdf";
import  Component, OnInit, Input, ElementRef, ViewChild  from '@angular/core';

@Component(
  selector: 'app-services',
  templateUrl: './services.component.html',
  styleUrls: ['./services.component.css']
)

export class ServicesComponent 

  @ViewChild("output", 
    static: true
  ) output: ElementRef;


  serviceItems: ServiceItem[];
  invoice: Invoice; //from invoice.ts

  constructor(private dialog: MatDialog, private serviceHelper: ServiceHelper, private _snackBar: MatSnackBar) 

    this.invoice = new Invoice();
    this.serviceItems = serviceHelper.getServices();
  

  clearInvoice(): void 
    /**
     * Iterate over the beverages array and set each objects checked property to false.
     */
    for (let service of this.serviceItems) 
      service.checked = false;
    

    this.invoice = new Invoice(); // return a new instance of the Bill object.
  


  openSnackBar(message: string) 
    this._snackBar.open(message + " was added!");
  

  //Opens modal with calculated results
  submit() 

    console.log(this.serviceItems)


    for (let item of this.serviceItems) 
      if (item.checked) 
        this.invoice.addServiceItem(item);
      
    

    console.log(this.invoice.serviceItems);
    console.log(this.invoice.getTotal());

    const dialogRef = this.dialog.open(AuthLayoutComponent, 
      data: 
        invoice: this.invoice
      ,
      disableClose: true,
      width: '800px'
    )


    dialogRef.afterClosed().subscribe(result => 
      if (result === 'confirm') 
        alert('Your order has been processed!');
        this.clearInvoice();
       else 
        alert('Your order has been canceled.');
        this.clearInvoice();
      
    )

  

【问题讨论】:

【参考方案1】:

您是否将 MatDialogModule 添加到您的 app.module.ts 中?

它应该看起来像这样

import MatDialogModule from '@angular/material/dialog';

@NgModule(
  ...
  imports: [
    ...
    MatDialogModule
    ...
  ]
)

export class AppModule 

https://material.angular.io/components/dialog/api

【讨论】:

是的,我已经导入了 是services.component.ts的同一个模块导入的吗?是的,请检查这个问题,即使它有点老了***.com/questions/47270324/…

以上是关于如何修复 Angular 中的此错误并将数据输出到 PDF?的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 如何修复表格视图单元格中的此动画向左然后再次返回

如何解决贝宝沙箱中的此错误

在Angular中将项目从v10迁移到v12后如何修复错误[关闭]

更新:如何修复过程语句中的 SQL 错误:新错误 [重复]

如何修复 Ionic 中的“没有导出的成员 'VeiwChild'”错误

如何解决 WNetAddConnection2 中的此错误“ERROR_BAD_USERNAME”?