我正在尝试将我的动态组件加载程序从RC4更新为RC5,因为不推荐使用ComponentResolver。我已将加载程序更新为以下
@Component({
selector: 'component-dispatcher',
template: `<div #container></div>` // Define the template here because of its brevity
})
export class ComponentDispatcherComponent implements OnInit, OnDestroy {
@Input() component:any; // Some dynamic component to render
@Input() options:any; // Component configuration, optional
@Input() data:any; // Data to render within the component
// Inject the dynamic component onto the DOM
@ViewChild("container", {read: ViewContainerRef}) container:ViewContainerRef;
private componentReference:ComponentRef<any>;
constructor(private resolver:ComponentFactoryResolver) {
}
ngOnInit() {
// Create our component now we're initialised
let componentFactory = this.resolver.resolveComponentFactory(this.component);
this.componentReference = this.container.createComponent(componentFactory);
this.componentReference.instance.data = this.data;
this.componentReference.instance.options = this.options;
}
ngOnDestroy() {
// If we have a component, make sure we destroy it when we lose our owner
if (this.componentReference) {
this.componentReference.destroy();
}
}
}
尝试将以下组件动态加载到DOM
中@Component({
selector: 'text-cell',
pipes: [IterableObjectPipe],
templateUrl: './text-cell.component.html',
styles: ['.fieldName { font-weight: bold; }']
})
export class TextCellComponent implements OnInit {
// Data to render within the component
@Input() data: any;
@Input() record: any;
// Configuration of what data to display
@Input() options: {
excludeFieldNames: boolean,
translation: string
};
constructor() {
}
ngOnInit() {
setTimeout(() => {
//console.log('***************************** ngOnInit...textCell ***********************');
this.options.translation = '' + (_.get(this.options, 'translation') || 'fields');
});
}
}
然而,当我使用我的TextCellComponent或应用程序中的任何其他组件执行此操作时,我收到以下错误
ORIGINAL EXCEPTION: No component factory found for TextCellComponent
ORIGINAL STACKTRACE:
Error: No component factory found for TextCellComponent
at NoComponentFactoryError.BaseException [as constructor]
(webpack:///./~/@angular/core/src/facade/exceptions.js?:27:23)
at new NoComponentFactoryError
我已经完成了
中的步骤https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html
但我似乎错过了一些东西。我已经尝试将组件添加到bootstrapping并在全局定义它们而没有运气。任何的意见都将会有帮助。
修改
添加模块定义
@NgModule({
imports: [
BrowserModule,
HttpModule,
FormsModule,
ReactiveFormsModule,
...MATERIAL_MODULES
],
declarations: [
...APPLICATION_PIPES,
...APPLICATION_COMPONENTS,
...APPLICATION_DIRECTIVES,
CygnusComponent,
// Component declarations
// TODO: refactor to appropriate modules
...
ComponentDispatcherComponent,
TextCellComponent,
...
],
bootstrap: [
ApplicationComponent
],
providers: [
...APPLICATION_PROVIDERS,
AppStore
]
})
export class ApplicationComponent {}
答案 0 :(得分:97)
即将加载的所有组件&#34;动态&#34;需要在模块的entryComponents
部分声明。换句话说,你应该得到类似的东西:
@NgModule({
imports: [BrowserModule, HttpModule, FormsModule, ReactiveFormsModule, ...MATERIAL_MODULES],
declarations: [...APPLICATION_PIPES, ...APPLICATION_COMPONENTS, ...APPLICATION_DIRECTIVES, CygnusComponent,
// Component declarations
// TODO: refactor to appropriate modules
...
ComponentDispatcherComponent,
TextCellComponent,
...
entryComponents: [TextCellComponent]
bootstrap: [ApplicationComponent],
providers: [...APPLICATION_PROVIDERS, AppStore]
})
export class ApplicationComponent{
请注意,您需要在{em> {/ 1>} 和 TextCellComponent
部分列出declarations
。
答案 1 :(得分:1)
您可能想要检查导入路径。在我的例子中,一个文件导入使用大写,而另一个使用小写。
//file 1
import { IRComponent } from "./components/IR/IR.component";
//file 2
import { IRComponent } from "./components/ir/ir.component";
赠送是在Chrome网络标签中,我注意到文件被加载了两次(每次拼写一次)。
答案 2 :(得分:1)
假设TextCellComponent
在FooModule
中声明,而您负责创建动态内容的组件在模块BarModule
中。
在这种情况下,需要将FooModule
导入BarModule
@NgModule({
imports: [FooModule],
declarations: [ComponentDispatcherComponent]
})
export class BarModule {}
在我看来,这有点使事物成为动态的想法。我只想要一个组件,它将创建通过类引用发送给它的任何组件。如果有人有不错的解决方案,我将很高兴听到它。
答案 3 :(得分:0)
即使您在EntryComponents和声明中提供了Component,有时也会遇到此问题。
在这些情况下,您只需输入此组件名称(此处为TextCellComponent
),如下所示:
declarations: [
TextCellComponent // Declared above
CygnusComponent,
ComponentDispatcherComponent,
...
]
这也应该在entryComponents中完成。
希望有所帮助。
答案 4 :(得分:-1)
您需要在// Define a Place ID.
String placeId = "INSERT_PLACE_ID_HERE";
// Specify the fields to return.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.newInstance(placeId, placeFields);
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
Log.i(TAG, "Place found: " + place.getName());
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place not found: " + exception.getMessage());
}
});
中导入MatDialogModule
,以使其了解那里的Module
。