【发布时间】:2021-02-14 14:52:22
【问题描述】:
我目前正在开发一个 Angular 应用程序。在我的一种方法中,我动态创建了一个组件,但是我无法使用组件中的CommonModule 中的ngClass、ngIf 和其他此类指令。
以下是错误示例:
Error when I use ngIf or ngClass inside the dynamically loaded logo component
我已经做了什么:
- 我已经在我的项目 app.module.ts 中导入了 commonModule
- 我已经在我的显示组件中导入了 commonModule,它可以正常工作,因为我可以在所有其他组件中使用 ngIf 和 ngClass 而没有任何问题
- 此外,只要我没有在我的 html 中使用 CommonModule 中的任何指令,我就可以毫无错误地导入任何组件
- 我尝试通过组件工厂 createComponent 函数导入 NgModule 的实例,如angular documentation 所示:
Quick view of angular documentation on component factory createcomponent
我已经为此花费了数小时,并认为这与我使用 createComponent 方法有关。
请帮忙!
这是我的 app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule, HammerGestureConfig, HammerModule,
HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { GoogleAnalyticsService } from
'./shared/services/googleanalytics'; // import our Google Analytics
service
import { BrowserAnimationsModule } from '@angular/platform-
browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [AppComponent],
imports: [
CommonModule,
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
],
providers: [GoogleAnalyticsService],
bootstrap: [AppComponent],
})
export class AppModule {}
这是我的显示组件 (Bdoc-a.component.ts)
import {
Component, OnInit, Input, Output, Renderer2, AfterViewInit,
AfterContentChecked, ViewChild, ElementRef,
ComponentFactoryResolver, ViewContainerRef, ViewChildren, QueryList
} from '@angular/core';
import { StorageService } from
'../../../../shared/services/storage.service';
import { AuthService } from '../../../../auth/auth.service';
@Component({
selector: 'app-bdoc-a',
templateUrl: './bdoc-a.component.html',
styleUrls: ['./bdoc-a.component.scss'],
})
export class BdocAComponent implements OnInit, AfterViewInit,
AfterContentChecked {
@Input() docConfig = { aspectRatio: '4:3', width: 800, height: 500 };
@Input() bgStyles = { shadow: true, bgClr: '#ffcc00' };
@Input() showBtns = false;
fWidth = this.docConfig.width;
fMaxWidth = this.docConfig.width;
fHeight = this.docConfig.height;
fMaxHeight = this.docConfig.height;
@Input() url = '';
@Input() settings = { ... };
...
@ViewChildren('loadDynAssetElEditItms', { read: ViewContainerRef })
biEditEls: QueryList<ViewContainerRef>;
@ViewChildren('loadDynAssetElViewItms', { read: ViewContainerRef })
biViewEls: QueryList<ViewContainerRef>;
loadDynAssetEl: any;
@ViewChild('bieditorFloat', { read: ElementRef }) bieditorFloat:
ElementRef;
@ViewChild('bieditorFloatViewer', { read: ElementRef })
bieditorFloatViewer: ElementRef;
// variable to hold all document page elements
allDocPages: any;
allDocPageComp = [];
constructor(private storage: StorageService,
private resolver: ComponentFactoryResolver,
private authService: AuthService,
private elmRef: ElementRef) {
this.url = 'templates/logo/1/logo1a/logo1a.component';
}
ngAfterViewInit(): void {
this.initBrandAsset();
}
initBrandAsset(): void {
this.allDocPageComp = [];
setTimeout(() => {
for (let i = 0; i < this.pages; i++) {
this.loadDynAsset(this.url, i);
}
this.setDocPageVar();
}, 200);
}
async loadDynAsset(url, pgIndex) {
const impEl = await import( 'src/app/' + url);
const allKeys = Object.keys(impEl);
this.biEditEls.forEach((itm, i) => {
if (i === pgIndex) {
itm.clear();
const newComp = itm.createComponent(
this.resolver.resolveComponentFactory(impEl[allKeys[0]]));
newComp.instance['bol']['test'] = 'LOGO TEST TEXT HERE... ' + pgIndex;
this.allDocPageComp.push(newComp.instance);
}
});
}
}
这是我的 Logo1a.component.html
<div class="baItem biLogo logo1a edit">
<div class="null bilNull">
<ng-container>
<div class="bilSymb">
<div class="null">
<div #forTxtLogo class="forTxtLogo" *ngIf="config.symb.mode ===
'txt'">
<div class="symbItm"><div class="nl">B</div></div><div
class="symbItm"><div class="nl">S</div></div>
</div>
<div #forImgSvgLogo class="forImgSvgLogo" *ngIf="config.symb.mode
=== 'svg' || config.symb.mode === 'img'">
<div class="symbItm"><div class="nl"></div></div>
</div>
</div>
</div><!-- end of bilSymb -->
</ng-container>
<ng-container *ngIf="config.body.show">
<div class="bilBody">
<div class="null">
<ng-container *ngIf="config.body.txt.show">
<div #forTxtArea class="forTxtArea">
<div class="null">Logo Body Text Area</div>
</div>
</ng-container>
<ng-container *ngIf="config.body.tag.show">
<div #forTagArea class="forTagArea"><div class="null">Logo Tag
Area...</div></div>
</ng-container>
</div>
</div><!-- end of bilBody -->
</ng-container>
</div><!-- end of biNull -->
</div><!-- end of biLogo-->
这是我的 Logo1a.component.ts
import { NgModule, Component, OnInit, Input, Output, Renderer2,
AfterViewInit, AfterContentChecked, ViewChild, ElementRef,
ComponentFactoryResolver, ViewContainerRef, ViewChildren, QueryList
} from '@angular/core';
import { StorageService } from
'../../../../shared/services/storage.service';
import { AuthService } from '../../../../auth/auth.service';
@Component({
selector: "app-logo1a",
templateUrl: "./logo1a.component.html",
styleUrls: ["./logo1a.component.scss"],
})
export class Logo1aComponent implements OnInit, AfterViewInit {
@ViewChild('loadExtra', { read: ViewContainerRef }) loadExtra:
ViewContainerRef;
@Input() bol = { test: 'LOGO 1A LOADED!' }; // breadth of life
public config = {
symb: {
show: true,
mode: 'txt', // 'txt', 'symb', 'img'
},
body: {
show: true,
txt: { show: true },
tag: { show: true }
}
}
constructor(private storage: StorageService,
private resolver: ComponentFactoryResolver,
private vcRef: ViewContainerRef,
private authService: AuthService,
private elmRef: ElementRef) { }
ngOnInit(): void {}
ngAfterViewInit() {}
}
这是我的 Logo1a.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Logo1aComponent } from './logo1a.component';
@NgModule({
imports: [CommonModule],
declarations: [Logo1aComponent],
exports: [Logo1aComponent]
})
export class Logo1aModule {}
但这是我在我的 Angular 10 应用程序中动态导入模块而不是组件后引发的错误,正如@jburtondev 建议的那样:
错误错误:未捕获(在承诺中):错误:断言错误:传入的类型不是 ComponentType,它没有 'ɵcmp' 属性。 ....
【问题讨论】:
-
Hey Bode,欢迎来到堆栈溢出!很高兴有你。你能发布你的代码吗?
-
嗨@jburtondev 感谢您的帮助。我应该在重新编辑我的原始帖子时将代码发布在 cmets 中吗?
-
很高兴,请。
-
嗨,博德!有趣的是,几个月前我也发生过类似的事情。原来我已经过度设计了那个组件,我根本不需要使用
ViewContainerRef,只需要一个简单的 ngFor 循环就可以实现我想要的。我建议您像 @jburtondev 所做的那样,使用一些代码和业务需求编辑您的问题,以便我们为您提供帮助 -
@jburtondev 好的会这样做...谢谢
标签: javascript angular typescript