[英]How can I fix this error in Angular and output data to a PDF?
I'm trying to output data to a PDF with a button in a modal that is also displaying the same data.我正在尝试使用模式中的按钮将 output 数据发送到 PDF,该按钮也显示相同的数据。 I have the data displaying in the modal with no issues, but I'm trying to create an option for the results to be downloaded to a PDF. I've been following a tutorial but currently receive an error in the console when loading my web application我的数据显示在模式中没有问题,但我正在尝试创建一个选项,以便将结果下载到 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!
I have a separate component just for holding the data and markup of the modal so that's where I'm also trying to implement the ability for a PDF option as well, in my auth-layout.component.ts我有一个单独的组件,仅用于保存模态的数据和标记,因此我也在尝试在我的 auth-layout.component.ts 中实现 PDF 选项的功能
Here's my auth.component.html这是我的 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">
{{ 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>
and here's the auth-layout.component.ts这是 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 {}
}
my services.component.ts as well, where i actually open the modal我的 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();
}
})
}
}
did you add MatDialogModule to your app.module.ts?你把 MatDialogModule 添加到你的 app.module.ts 了吗?
it should look something like this它应该看起来像这样
import {MatDialogModule} from '@angular/material/dialog';
@NgModule({
...
imports: [
...
MatDialogModule
...
]
})
export class AppModule {}
https://material.angular.io/components/dialog/api https://material.angular.io/components/dialog/api
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.