英文:
How to dynamically create Angular(15) component?
问题
It appears you're trying to translate some code related to Angular component creation and compilation. Here's the translated code:
我有一个函数,它可以创建一个内存中的Angular组件,将其添加为内存中的Angular模块的声明,然后编译它。
类似这样的代码:
```typescript
createComponent(template, selector) {
@Component({
selector: selector,
template: template
})
class AngularComponent implements OnInit, AfterViewInit
{
@Output() onAfterViewInit = new EventEmitter<boolean>();
ngOnInit(): void {
// 一些事件处理
}
ngAfterViewInit(): void {
// 一些事件处理
}
}
@NgModule({
declarations: [AngularComponent],
imports: [],
exports: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TemplateModule {
}
const compiled = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
}
这段代码在Angular 10下工作正常。但是,自从引入Ivy编译器后,在Angular 15下不再工作。是否有人可以建议如何更新上述函数,使其与Angular 15兼容?
编辑
我尝试了以下方法:
class AngularComponent {
}
const componentType = Component({ template: html, selector: selectedComponent })(AngularComponent);
这个方法可以正常工作,但是当我为AngularComponent
添加implements OnInit, AfterViewInit
之后,会出现以下错误:
error NG2007: 类使用了Angular功能,但没有装饰器。请添加明确的Angular装饰器。
编辑 2
基于@Anton的评论,我进行了以下更改:
createComponent(template, selector) {
@Directive()
class AngularComponent implements OnInit, AfterViewInit {
@Output() onAfterViewInit = new EventEmitter<boolean>();
ngOnInit(): void {
// 方法调用
}
ngAfterViewInit(): void {
this.onAfterViewInit.emit();
}
}
const angularComponentType = Component({
template: html,
selector: selectedComponent
})(AngularComponent);
}
现在,ng build
可以正常工作,但在浏览器控制台上运行ng serve
时,我收到以下错误消息:
Error: NG0202: 此构造函数与Angular依赖注入不兼容,因为其参数列表中索引为0的依赖项无效。
这可能是因为参数列表中索引为0的依赖项类型是原始类型,比如字符串,或者这个类的祖先缺少Angular装饰器。
请检查以下内容:1) 索引为0的参数的类型是否正确,2) 此类及其祖先是否定义了正确的Angular装饰器。
希望这有助于您更新代码以使其与Angular 15兼容。如果您有其他问题,请随时提出。
英文:
I have a function which would create an In memory angular component, add it as a declaration for an In memory Angular Module and then compile the same
something like this:
createComponent(template, selector) {
@Component({
selector: selector,
template: template
})
class AngularComponent implements OnInit, AfterViewInit
{
@Output() onAfterViewInit = new EventEmitter<boolean>();
ngOnInit(): void {
// some event
}
ngAfterViewInit(): void {
// some event
}
}
@NgModule({
declarations: [AngularComponent],
imports: [],
exports: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TemplateModule {
}
const compiled = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
}
This used to work for Angular 10. But, since Ivy compiler is introduced now, it would not work for Angular 15. Could anyone please suggest updates for the above function to make it compatible for Angular 15?
Edit
I tried the following:
class AngularComponent {
}
const componentType = Component({ template: html, selector: selectedComponent})(AngularComponent);
This works until I add implements OnInit, AfterViewInit
for AngularComponent
Once I add the same, I get following error:
error NG2007: Class is using Angular features but is not decorated. Please add an explicit Angular decorator.
EDIT 2
Based on @Anton's comment, I made following changes:
createComponent(template, selector) {
@Directive()
class AngularComponent implements OnInit, AfterViewInit{
@Output() onAfterViewInit = new EventEmitter<boolean>();
ngOnInit(): void {
// method call
}
ngAfterViewInit(): void {
this.onAfterViewInit.emit();
}
}
const angularComponentType = Component({
template: html,
selector: selectedComponent
})(AngularComponent);
}
Now the ng build
works, but on ng serve
I am getting error on browser console:
Error: NG0202: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
答案1
得分: 0
如果您的示例有效,请为其添加Angular装饰器。
@Directive()
class AngularComponent {}
const componentType = Component({ template: html, selector: selectedComponent })(AngularComponent);
然后在代码中的某个地方使用它:
this.viewContainerRef.createComponent(componentType, {
injector: this.injector,
});
英文:
If your example works, just add Angular decorator for this.
@Directive()
class AngularComponent {}
const componentType = Component({ template: html, selector: selectedComponent})(AngularComponent);
And then use it somewhere in your code:
this.viewContainerRef.createComponent(componentType, {
injector: this.injector,
});
答案2
得分: 0
Here is the translated content:
在进行更改和适当的测试后,以下是对我有效的内容:
创建一个组件作为基类
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
@Component({
template: ''
})
export class AngularComponent implements OnInit {
@Output() onAfterViewInit = new EventEmitter<boolean>();
ngOnInit(): void {
this.onAfterViewInit.emit();
}
}
然后创建一个扩展基类的动态组件:
import { Component } from '@angular/core';
createComponent(html, selector) {
const angularComponentType = Component({
template: html,
selector: selector
})(class extends AngularComponent {
ngOnInit(): void {
localfunction(this);
}
});
}
英文:
After making changes and proper testing here is what worked for me:
Created a component as base class
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
@Component({
template: ''
})
export class AngularComponent implements OnInit {
@Output() onAfterViewInit = new EventEmitter<boolean>();
ngOnInit(): void {
this.onAfterViewInit.emit();
}
}
And then created a dynamic component extending the base class:
import { Component } from '@angular/core';
createComponent(html, selector) {
const angularComponentType = Component({
template: html,
selector: selector
})(class extends AngularComponent {
ngOnInit(): void {
localfunction(this);
}
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论