[英]Angular 11 print component inside another component
I have a simple component where I've placed multiple buttons and I want to show those buttons in another component (functionality of buttons also comes from my buttons component) but i get this error in terminal我有一个简单的组件,我在其中放置了多个按钮,我想在另一个组件中显示这些按钮(按钮的功能也来自我的按钮组件),但我在终端中收到此错误
ERROR NullInjectorError: R3InjectorError(HelpdeskModule)[ButtonsComponent -> ButtonsComponent -> ButtonsComponent -> ButtonsComponent]:
NullInjectorError: No provider for ButtonsComponent!
buttons.component.html
<div class="mb-3">
<nz-button-group>
<button nz-button nzType="primary" (click)="buttonClick('create button')" class="ant-btn ant-btn-primary ant-btn-lg"><i nz-icon nzType="download"></i>Create New</button>
</nz-button-group>
</div>
list.component.ts
(this is where i want to show those components) list.component.ts
(这是我想展示这些组件的地方)
import { ButtonsComponent } from 'src/app/components/app/layout/buttons/buttons.component';
constructor(
private buttons: ButtonsComponent,
) { }
And list.component.html
和list.component.html
// I am uncertain about this part to be correct at all!
{{buttons}}
Any idea?任何的想法?
I've added Injectable
to my buttons component like this: (just playing around to get them printed )我已经将Injectable
添加到我的按钮组件中,如下所示:(只是为了打印它们)
import { Component, OnInit, Injectable } from '@angular/core';
import { NzNotificationService } from 'ng-zorro-antd'
@Component({
selector: 'app-buttons',
templateUrl: './buttons.component.html',
styleUrls: ['./buttons.component.scss']
})
@Injectable({
providedIn: 'root'
})
export class ButtonsComponent implements OnInit {
//
}
and now I'm getting this error现在我收到了这个错误
ERROR TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
First thing, inside list.component.html
just place html like below首先,在list.component.html
放置如下所示的 html
<app-buttons></app-buttons>
And then you want to call method of of ButtonsComponent
, use it as a dependency, you have to keep it in providers array first.然后你想调用ButtonsComponent
方法,将它用作依赖,你必须先将它保存在 providers 数组中。
providers: [
...,
ButtonsComponent,
...
]
But as I look through your updated question, you don't have to inject the component inside constructor, rather you can use ViewChild
.但是当我查看您更新的问题时,您不必将组件注入构造函数中,而可以使用ViewChild
。
@ViewChild('buttons', { static: false, read: ViewContainerRef })
buttons: ButtonsComponent;
list.component.html列表.component.html
<app-buttons #buttons></app-buttons>
Using ComponentFactoryResolver in Angular to handle dynamic loader for multiple components:在 Angular 中使用 ComponentFactoryResolver 来处理多个组件的动态加载器:
Here is sample code:这是示例代码:
import {
Component,
ComponentFactory,
ComponentRef,
ComponentFactoryResolver,
ViewContainerRef,
ViewChild
} from '@angular/core'
import { AComponent } from './a.component';
import { BComponent } from './b.component';
@Component({
selector: 'modal-resolver',
template: `
<template #modalContainer></template>
`,
})
export class ModalResolver {
@ViewChild("modalContainer", { read: ViewContainerRef }) container;
@Input() name;
componentRef: ComponentRef;
listComponent: {
'modalA': AComponent,
'modalB': BComponent
}
constructor(private resolver: ComponentFactoryResolver) { }
ngOnInit() {
this.loadComponent(this.name);
}
loadComponent(type) {
this.container.clear();
const factory: ComponentFactory = this.resolver.resolveComponentFactory(this.listComponent[this.name]);
this.componentRef = this.container.createComponent(factory);
this.componentRef.instance.type = type;
this.componentRef.instance.output.subscribe(event => console.log(event));
}
ngOnDestroy() {
this.componentRef.destroy();
}
}
Then you use it:然后你使用它:
<modal-resolver name="modalA"></modal-resolver>
printComponent(elementId: any, scape: any = 'landscape') { const originalContents = document.body.innerHTML; const printContents = document.getElementById(elementId).innerHTML; const css = '@page { size: ' + scape + '; }'; const head = document.head || document.getElementsByTagName('head')[0]; const style: any = document.createElement('style'); style.type = 'text/css'; style.media = 'print'; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style); document.body.innerHTML = printContents; window.print(); document.body.innerHTML = originalContents; window.location.reload(); }
<div> <h3>Page d'impression des états</h3> <button nbButton size="tiny" outline status="warning" class="align-middle" (click)="printComponent('componentId')" > <nb-icon icon="print-outline"></nb-icon> IMPRIMER </button> <div id="usersId"> <table class="table" id="componentId"> <thead> <tr> <th scope="col">Class</th> <th scope="col">Heading</th> <th scope="col">Heading</th> </tr> </thead> <tbody> <ng-container *ngFor="let i of [].constructor(100)"> <tr> <th scope="row">Default</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-primary"> <th scope="row">Primary</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-secondary"> <th scope="row">Secondary</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-success"> <th scope="row">Success</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-danger"> <th scope="row">Danger</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-warning"> <th scope="row">Warning</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-info"> <th scope="row">Info</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-light"> <th scope="row">Light</th> <td>Cell</td> <td>Cell</td> </tr> <tr class="table-dark"> <th scope="row">Dark</th> <td>Cell</td> <td>Cell</td> </tr> </ng-container> </tbody> </table> </div> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.