我正在MyComponent使用以下代码动态加载 Angular 组件 ( )。创建组件后,我还将一些数据传递给组件。
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
this.viewContainerRef.clear();
let componentRef = this.viewContainerRef.createComponent(componentFactory);
(<MyComponent>componentRef.instance).setData(data);
Run Code Online (Sandbox Code Playgroud)
什么时候会触发OnInit生命周期事件MyComponent?调用后会立即触发createComponent()吗?或者它只会在之后被调用setData()?
我有一个 mat-tab-group (角度材料),我希望能够从 mat-tabs 后面的代码添加,包括其他组件。我正在使用 ComponentFactoryResolver 创建组件,但无法通过 ViewContainerRef 将新组件添加到新的 mat-tab
html
<mat-tab-group>
<mat-tab *ngFor="let tab of tabs" [label]="tab.title">
<div #test></div>
</mat-tab>
</mat-tab-group>
Run Code Online (Sandbox Code Playgroud)
代码隐藏
private open(type:string):void{
var tab = {title:'test'};
this.tabs.push(tab);
const factory = this.componentFactoryResolver.resolveComponentFactory(DiscountGridComponent );
//this will add it in the end of the view
const newComponentRef = this.viewContainerRef.createComponent(factory);
}
Run Code Online (Sandbox Code Playgroud) 我有一个滑块,其中是动态创建的项目 - 这些是子组件。
滑块的 ng-container 父模板:
<div id="slider-wrapper">
<ng-container appSliderForm *ngFor="let question of questionsInSlider"
[questionTest]="question" (onRemove)="removeQuestion($event)">
</ng-container>
</div>
Run Code Online (Sandbox Code Playgroud)
这些子组件由 appSliderForm 指令创建:
@Directive({
selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {
@Input()
questionTest: QuestionInSlider;
constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}
ngOnInit(): void {
const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
const component = this.container.createComponent(factory);
component.instance.questionTest = this.questionTest;
component.instance.ref = component;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的子组件中,我有一个删除功能,用于将自身从滑块中删除。
@Component({
selector: 'app-test-question-in-slider',
templateUrl: './test-question-in-slider.component.html',
styleUrls: ['./test-question-in-slider.component.less']
})
export class TestQuestionInSliderComponent {
questionTest: QuestionInSlider;
ref: any;
@Output() …Run Code Online (Sandbox Code Playgroud) angular-directive angular angular5 angular-event-emitter angular-dynamic-components
我正在构建一个带有动态选项卡的对话框,该对话框可以接收要放置在选项卡主体中的组件。我很难使用 @ViewChildren 创建多个动态组件。我过去已经很容易地使用单个组件和 @ViewChild 成功地完成了此操作。
这是我的模板:
<mat-tab *ngFor="let tab of tabs" [label]="tab.label">
<ng-template #comp></ng-template>
</mat-tab>
Run Code Online (Sandbox Code Playgroud)
这是我的组件逻辑:
@ViewChildren("comp") dynComponents: QueryList<any>;
public ngAfterContentInit() {
this.tabs.forEach(tab => {
const factory = this._resolver.resolveComponentFactory(tab.component);
console.log(this.dynComponents); // Returns undefined.
// this.componentRef = this.vcRef.createComponent(factory);
});
}
Run Code Online (Sandbox Code Playgroud)
即使在模板中对组件进行硬编码,我的 dynComponents 也未定义。我似乎需要从这个 dynComponents QueryList 获取 ViewContainerRef,但我不确定为什么它根本没有填充。我用这篇文章作为参考:帖子
我将动态地将组件与服务中的另一个组件进行比较,首先,在服务工厂中同时对两个组件进行创建,然后创建可以访问ViewContainer的组件。但是无法创建组件!
服务内容:
@Injectable({
providedIn: 'root'
})
export class ModalService {
componentRef: ComponentRef<ModalTemplateComponent>;
constructor(private _modalService: BsModalService,
private resolver: ComponentFactoryResolver,
private injector: Injector) {
}
open(componentType: any) {
const contentFactory = this.resolver
.resolveComponentFactory(componentType);
const templateFactory = this.resolver
.resolveComponentFactory(ModalTemplateComponent);
const componentRef = templateFactory.create(this.injector);
componentRef.instance.container.createComponent(contentFactory);
this._modalService.show(componentRef.componentType, {class: 'modal-lg', initialState: {data: {test:true}});
}
}
Run Code Online (Sandbox Code Playgroud)
零件 :
selector: 'lib-modal-template',
template: `
<h1>{{title}}</h1>
<ng-container #container>
</ng-container>
`,
styleUrls: ['./modal-template.component.css']
})
export class ModalTemplateComponent implements OnInit {
title:string;
@ViewChild('container', {read: ViewContainerRef, static: true}) container: ViewContainerRef;
}
Run Code Online (Sandbox Code Playgroud)
例如:
this._modalService.open(NewUserForm,...);
[innerHTML]属性并创建动态Reactive Forms来绑定到输入来解决此要求.但是,由于使用innerHTML属性的技术限制,该方法失败.一旦HTML在浏览器中呈现,所有属性都被强制为小写文本,因此任何Angular指令或属性都会失败.比如*ngIf, *ngFor, [formGroup], formControlName等...... Angular使用camelCase几乎所有东西,因此一旦它被强制为小写文本,它就会被忽略,这种方法不再是一个可行的解决方案.
[innerHTML]属性,再次使这个方法无用(如我第一次尝试中所述).
通过使用此方法,显示动态组件HTML,但是我收到一个新错误:"错误错误:formGroup需要一个FormGroup实例.请传入一个."
我经历了角度动态加载组件。但是我找不到如何动态删除组件。
我的要求是聊天应用程序根据对话加载动态组件(图像/图形/列表/表)。但是,如果对话继续进行,我该如何销毁该组件。
我正在尝试通过外部事件破坏动态组件。
请帮助如何进行。
编辑:https : //stackblitz.com/angular/emjkxxxdxmk? file = src%2Fapp%2Fad- banner.component.ts
我根据此示例开发了代码。而不是时间间隔,我需要使用来自订阅了另一个组件(聊天组件)的服务的API调用。
下面的API响应可以加载该组件。我正在寻找如何销毁已经加载的组件,我再次使用API调用。
public sendMessage(data): void {
this.messages.push(this.message);
this.API.getResponse(data).subscribe(res => {
this.previousContext = res.context;
console.log('res', res);
if (res.result.type == 'table') {
this.DataService.setTrigger(new AdItem(Table2Component, res));
}
this.messages.push(
new Message(res.text, 'assets/images/bot.png', new Date(), 'chatbot')
);
});
this.message = new Message('', 'assets/images/user.png', this.message.timestamp, 'user');
}
Run Code Online (Sandbox Code Playgroud) 我正在为我的一个项目实现动态组件.动态组件的概念是它们在需要时进入内存并且在任何模板中都没有引用.
根据官方文档,我们声明这些组件entryComponents以防止它们在树摇动过程中被丢弃,因为它们没有模板参考.
以下是app.module.ts我在那里宣布我的两个动力组件SlideOneComponent,并SlideTwoComponent在在entryComponents阵:
@NgModule({
declarations: [
AppComponent,
ButtonComponent,
AdDirective
],
imports: [
BrowserModule
],
providers: [],
entryComponents: [
SlideOneComponent,
SlideTwoComponent,
],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
上面app.module.ts我得到以下错误:
一旦我将两个动态组件添加到declarations数组,上述错误就会消失.上述官方文档还说我们不需要声明可从组件entryComponents或bootstrap组件访问的组件.我也参观了这个答案,但这似乎并不令人满意,因为它与Ionic有关.
请帮我知道我在哪里失踪.提前致谢!:)
我使用angular 5的动态组件创建了n级嵌套展开/折叠功能.
功能上一切正常,但当我加载多个dom元素时,浏览器崩溃或滚动停止工作(Jerky Scroll)
基本上它的高级报告功能包括用户选择的过滤器和我们提供的维度.
以下是我开发的功能的工作原理
1)用户访问Web应用程序上的报告页面.2)用户选择过滤器和groupby参数,根据该参数我生成具有多行的基于div的表.
现在我保持条件检查,用户可以进一步扩展/折叠行,基于我使用group by维护的对象.这里group by表示用户可以使用的级别数
例如,按参数分组是国家,操作系统,Appname和Campaign,我将使用展开按钮为每行显示所有可用国家/地区的数据,单击展开按钮我将呈现另一个具有操作系统(OS)数据的表对于那个特定国家等等......
我实际上已经确定了为什么会出现性能问题,这可能是因为我正在检查由下一个groupby对象和isCollapsed参数标识的特定展开/折叠按钮.由于特定条件是多次定期检查滚动停止工作或浏览器开始执行缓慢
这是一段视频,说明了它的工作原理和滚动条性能
https://youtu.be/m1a2uxhoNqc
Run Code Online (Sandbox Code Playgroud)
我无法在plunker或任何其他在线工具上上传代码,因为它已经集成到我正在开发的具有实际数据的平台中.
由于stackoverflow字符限制,我无法在此处添加代码,但已创建了gist.
这是访问代码的URL:
https://drive.google.com/drive/folders/1ZxAS8yHd8iHJ6ds3mZhLR0bw6o0cnRL6?usp=sharing
Run Code Online (Sandbox Code Playgroud)
一旦性能问题得到解决,我想让代码更可重用.
看看这个,让我知道我的错误,以改善代码质量和性能问题.
谢谢.
typescript angular-components angular angular-dynamic-components
我发现这是一个解决方案,对其他人也很有用。
可以将其应用于任何未设置ViewContainerRef的本机元素。
我试图在点击事件中将角组件植入表(Tabulator v4.2)中。该表是由插件动态创建的,因此我无权访问需要为其设置角度ViewContainerRef的DOM元素。在click事件回调中,我可以访问要向其中添加角度分量的元素。
如何在未设置角度ViewContainerRef的情况下向该元素添加角度分量?
每次单击都应创建一个新组件,并将其设置在给定的DOM元素内。