Я пытаюсь обновить загрузчик динамических компонентов с 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
Но мне кажется что-то не хватает. Я попытался добавить компоненты в начальную загрузку и определить их глобально, но безуспешно. Любые предложения были бы полезны.
ИЗМЕНИТЬ
Добавление определения модуля
@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 {}
5 ответов
Все компоненты, которые будут загружаться «динамически», необходимо объявить в разделе 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{
Обратите внимание, что вам необходимо указать TextCellComponent
в обоих разделах declarations
и entryComponents
.
Вы можете проверить свои пути импорта. В моем случае при импорте одного файла использовались прописные буквы, а в другом - строчные.
//file 1
import { IRComponent } from "./components/IR/IR.component";
//file 2
import { IRComponent } from "./components/ir/ir.component";
Раздача была на вкладке сети Chrome, я заметил, что файл загружался дважды (один раз для каждого написания).
Допустим, TextCellComponent
объявлен в FooModule
, а ваш компонент, отвечающий за создание динамического контента, находится в модуле BarModule
.
В таком случае FooModule
необходимо импортировать в BarModule
@NgModule({
imports: [FooModule],
declarations: [ComponentDispatcherComponent]
})
export class BarModule {}
На мой взгляд, это как бы компрометирует идею о том, что вещи динамические . Мне просто нужен компонент, который создаст любой компонент, на который я отправлю его по ссылке на класс. Если у кого-то есть достойное решение, я был бы рад его услышать.
Вам необходимо импортировать {{X0}} в {{X1}}, чтобы он знал о {{X2}} там.…
В таких ситуациях вам просто нужно ввести это имя компонента (здесь TextCellComponent
) над всеми другими компонентами, как показано ниже:
declarations: [
TextCellComponent // Declared above
CygnusComponent,
ComponentDispatcherComponent,
...
]
Это также нужно сделать в entryComponents.
Надеюсь, это поможет.
Объект 'dict' не имеет атрибута 'aggregate'…
Похожие вопросы
Связанные вопросы
Новые вопросы
angular
Вопросы об Angular (не путать с AngularJS), веб-фреймворке от Google. Используйте этот тег для вопросов Angular, которые не относятся к отдельной версии. Для более старой веб-инфраструктуры AngularJS (1.x) используйте тег AngularJS.