Phiên bản góc tôi đã sử dụng - Angular 4.2.0
Angular 4 được đưa ra với ElementFactoryResolver để tải các thành phần khi chạy. Đây là một dạng triển khai tương tự của $ compile trong Angular 1.0, phục vụ nhu cầu của bạn
Trong ví dụ dưới đây, tôi đang tải thành phần ImageWidget một cách linh hoạt vào DashboardTileComponent
Để tải một thành phần, bạn cần một lệnh mà bạn có thể áp dụng cho ng-template sẽ giúp đặt thành phần động
WidgethostDirective
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[widget-host]',
})
export class DashboardTileWidgetHostDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}
lệnh này tiêm ViewContainerRef để có quyền truy cập vào vùng chứa khung nhìn của phần tử sẽ lưu trữ thành phần được thêm động.
DashboardTileComponent (Thành phần giữ chỗ để kết xuất thành phần động)
Thành phần này chấp nhận đầu vào đến từ các thành phần chính hoặc bạn có thể tải từ dịch vụ của mình dựa trên việc triển khai. Thành phần này đang đóng vai trò chính để giải quyết các thành phần khi chạy. Trong phương thức này, bạn cũng có thể thấy một phương thức có tên là renderComponent () cuối cùng tải tên thành phần từ một dịch vụ và giải quyết với ElementFactoryResolver và cuối cùng là thiết lập dữ liệu cho thành phần động.
import { Component, Input, OnInit, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { DashboardTileWidgetHostDirective } from './DashbardWidgetHost.Directive';
import { TileModel } from './Tile.Model';
import { WidgetComponentService } from "./WidgetComponent.Service";
@Component({
selector: 'dashboard-tile',
templateUrl: 'app/tile/DashboardTile.Template.html'
})
export class DashboardTileComponent implements OnInit {
@Input() tile: any;
@ViewChild(DashboardTileWidgetHostDirective) widgetHost: DashboardTileWidgetHostDirective;
constructor(private _componentFactoryResolver: ComponentFactoryResolver,private widgetComponentService:WidgetComponentService) {
}
ngOnInit() {
}
ngAfterViewInit() {
this.renderComponents();
}
renderComponents() {
let component=this.widgetComponentService.getComponent(this.tile.componentName);
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);
let viewContainerRef = this.widgetHost.viewContainerRef;
let componentRef = viewContainerRef.createComponent(componentFactory);
(<TileModel>componentRef.instance).data = this.tile;
}
}
DashboardTileComponent.html
<div class="col-md-2 col-lg-2 col-sm-2 col-default-margin col-default">
<ng-template widget-host></ng-template>
</div>
WidgetComponentService
Đây là một nhà máy dịch vụ để đăng ký tất cả các thành phần mà bạn muốn giải quyết một cách linh hoạt
import { Injectable } from '@angular/core';
import { ImageTextWidgetComponent } from "../templates/ImageTextWidget.Component";
@Injectable()
export class WidgetComponentService {
getComponent(componentName:string) {
if(componentName==="ImageTextWidgetComponent"){
return ImageTextWidgetComponent
}
}
}
ImageTextWidgetComponent (thành phần chúng tôi đang tải khi chạy)
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'dashboard-imagetextwidget',
templateUrl: 'app/templates/ImageTextWidget.html'
})
export class ImageTextWidgetComponent implements OnInit {
@Input() data: any;
constructor() { }
ngOnInit() { }
}
Thêm Cuối cùng, thêm ImageTextWidgetComponent vào mô-đun ứng dụng của bạn dưới dạng entryComponent
@NgModule({
imports: [BrowserModule],
providers: [WidgetComponentService],
declarations: [
MainApplicationComponent,
DashboardHostComponent,
DashboardGroupComponent,
DashboardTileComponent,
DashboardTileWidgetHostDirective,
ImageTextWidgetComponent
],
exports: [],
entryComponents: [ImageTextWidgetComponent],
bootstrap: [MainApplicationComponent]
})
export class DashboardModule {
constructor() {
}
}
Ngói
export interface TileModel {
data: any;
}
Tài liệu tham khảo từ blog của tôi
Tài liệu chính thức
Tải xuống mã nguồn mẫu