问题描述
尝试在动态创建的组件中使用服务时,运行时出现此错误
When trying to use a service in dynamically created component We got this error at run time
错误错误:无法解析 class_1 的所有参数:(?).在 syntaxError (compiler.js:485)在 CompileMetadataResolver._getDependenciesMetadata (compiler.js:15664)在 CompileMetadataResolver._getTypeMetadata (compiler.js:15499)在 CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:15007)在 CompileMetadataResolver.loadDirectiveMetadata (compiler.js:14862)在 eval (compiler.js:34233)在 Array.forEach ()在 eval (compiler.js:34232)在 Array.forEach ()在 JitCompiler._loadModules (compiler.js:34229)
这是一个示例代码
import { Compiler, Component, Injector, VERSION, ViewChild, NgModule, NgModuleRef, OnInit, ViewContainerRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { CmsService } from "../../services/cms.service";
@Component({
selector: 'home-page',
template: `
<ng-container #vc></ng-container>
`
})
export class HomePageComponent implements OnInit {
constructor(private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>) { }
ngOnInit() {
}
@ViewChild('vc', { read: ViewContainerRef }) vc;
ngAfterViewInit() {
const tmpCmp = Component({ moduleId: module.id, templateUrl: '../../../assets/HomePage/home-page-rbu.component.html' })(
class {
constructor(public cms: CmsService) { }
welcomeTXT: string;
advertismentTXT: string;
ngOnInit() {
this.cms.getCMSItemValue('welcomeTXT').subscribe(res => {
this.welcomeTXT = res;
});
this.cms.getCMSItemValue('advertismentTXT').subscribe(res => {
this.advertismentTXT = res;
});
}
});
@NgModule({
imports: [BrowserModule, RouterModule],
declarations: [tmpCmp],
providers: [CmsService]
})
class DynamicModule { }
this._compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.name = 'dynamic';
this.vc.insert(cmpRef.hostView);
})
}
}
此示例代码在添加 CmsService 或任何角度服务之前运行良好我们正在使用 angular 5.1 和 angular-cli 1.5
this sample code was working fine before adding CmsService or any angular servicewe are using angular 5.1 and angular-cli 1.5
推荐答案
该问题的解决方法是使用 componentFactories 访问动态创建的组件的公共属性
Workaround for the issue is to access the public properties of the dynamic created componenet using the componentFactories
welcomeTXT: string;
advertismentTXT: string;
作为:
this._compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.welcomeTXT = _welcomeTXT;
cmpRef.instance.advertismentTXT = _advertismentTXT;
cmpRef.instance.visitorsCount = _visitorsCount;
cmpRef.instance.name = 'dynamic';
this.vc.insert(cmpRef.hostView);
})
这是组件的完整代码:
import { Compiler, Component, Injector, VERSION, ViewChild, NgModule, NgModuleRef, OnInit, ViewContainerRef} from '@angular/core';
import { BrowserModule, DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { CmsService } from "../../services/cms.service";
@Component({
selector: 'my-app',
template: `
<ng-container #vc></ng-container>
`
})
export class HomePageComponent implements OnInit {
@ViewChild('vc', { read: ViewContainerRef }) vc;
constructor(private _compiler: Compiler, private _cms: CmsService, private _injector: Injector, private _m: NgModuleRef<any>, private sanitizer: DomSanitizer) { }
ngOnInit() {
}
ngAfterViewInit() {
let welcomeTXT: any = "";
let advertismentTXT: any = "";
let visitorsCount: number = 0;
this._cms.getVisitorsCount().subscribe(res => {
visitorsCount = res;
});
this._cms.getCMSItemValue('welcomeTXT').subscribe(res => {
advertismentTXT = this.sanitizer.bypassSecurityTrustHtml(res);
this._cms.getCMSItemValue('advertismentTEXT').subscribe(res => {
welcomeTXT = this.sanitizer.bypassSecurityTrustHtml(res);
this.CreateHomePageComponent(welcomeTXT, advertismentTXT, visitorsCount);
});
});
}
CreateHomePageComponent(_welcomeTXT: any, _advertismentTXT: any, _visitorsCount: number) {
const tmpCmp = Component({ moduleId: module.id, templateUrl: '../../../assets/HomePage/home-page-rbu.component.html' })(
class {
welcomeTXT: string;
advertismentTXT: string;
visitorsCount: number = 0;
});
@NgModule({
imports: [BrowserModule, RouterModule],
declarations: [tmpCmp],
providers: [CmsService]
})
class DynamicModule { }
this._compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.welcomeTXT = _welcomeTXT;
cmpRef.instance.advertismentTXT = _advertismentTXT;
cmpRef.instance.visitorsCount = _visitorsCount;
cmpRef.instance.name = 'dynamic';
this.vc.insert(cmpRef.hostView);
})
}
}
我希望这对某人有所帮助
I wish this help someone
我们也可以将服务作为变量传递给visitorsCount
We can also pass the service as variable like visitorsCount
这篇关于尝试在动态创建的组件角度 5.1 中使用服务时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!