Angular2項目網站須要一個容器頁面,能夠展現用戶自定義開發的html文本(包含css,js,html等)javascript
以下圖,編輯好css,js及html後,在右側能夠實時查看展現效果,而且能夠執行按鈕事件。css
思路:html
定義一個通用組件容器接受js,css參數,組件中template對象加載html,styles對象加載css,並經過Renderer類注入js腳本。java
實現:app
1.建立樹組件 dynamic-com.component.tspost
import { SharedModule } from '../../../module/shared-module/shared-module';
import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
@Component({
selector: 'app-dynamic-com',
template: `
<ng-container *ngComponentOutlet="dynamicComponent; ngModuleFactory: dynamicModule;">
</ng-container>`,
styleUrls: ['./dynamic-com.component.css']
})
export class DynamicComComponent implements OnInit {
dynamicComponent: any;
dynamicModule: NgModuleFactory<any>;
@Input('html') html: string; //接收html
@Input('js') js: string;
@Input('css') css: string;
@Input('dataSource') dataSource: any; //html中須要綁定的數據源
constructor(private compiler: Compiler) { }
//改變後從新編譯生成html
ngOnChanges(changes: SimpleChanges) {
if (changes['html'] && !changes['html'].isFirstChange() ||
changes['css'] && !changes['css'].isFirstChange() ||
changes['js'] && !changes['js'].isFirstChange() ||
(changes['dataSource'] && !changes['dataSource'].isFirstChange())) {
this.dynamicComponent = this.createNewComponent(this.html, this.dataSource);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
}
ngOnInit() {
this.dynamicComponent = this.createNewComponent(this.html, this.dataSource);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
protected createComponentModule(componentType: any) {
@NgModule({
imports: [SharedModule],
declarations: [
componentType
],
entryComponents: [componentType]
})
class RuntimeComponentModule {
}
// a module for just this Type
return RuntimeComponentModule;
}
protected createNewComponent(template: string, dataSource: any) {
console.log(this.js + template);
let comJs = this.js;
let comCss = this.css;
@Component({
selector: 'dynamic-component',
template: template ? template : '<div></div>',
styles: [comCss]
})
class MyDynamicComponent {
public list: any = dataSource;
constructor(private _renderer2: Renderer2,
@Inject(DOCUMENT) private _document,
private elementRef: ElementRef) {
}
//注入js
ngAfterViewInit() {
if (comJs) {
var s = document.createElement("script");
s.type = "text/javascript";
//s.src = "http://";
//s.text = `function test(){alert(111);}`;
s.text = comJs;
this.elementRef.nativeElement.appendChild(s);
}
}
}
return MyDynamicComponent;
}
}
2.引入組件 網站
form-design.component.htmlthis
能夠經過<app-dynamic-com [js]="js" [css]="css" [html]="html" [dataSource]="list"></app-dynamic-com>來引入組件spa
<div id="CodeArea" style="float: left; height: 435px; width: 50%;margin-left: 5px;border-right: 1px solid #cfcfe6;">
<h2>編輯您的代碼:</h2>
<div style="width:45%;float:left;">
<h4>css:</h4>
<textarea [(ngModel)]="css"></textarea>
</div>
<div style="width:45%;float:left;">
<h4>js:</h4>
<textarea [(ngModel)]="js"></textarea>
</div>
<div style="width:100%;float:left;">
<h4>html:</h4>
<textarea [(ngModel)]="html"></textarea>
</div>
</div>
<div id="result" style="float: left; height: 435px;width: 49%;">
<h2>查看結果:</h2>
<br />
<app-dynamic-com [js]="js" [css]="css" [html]="html" [dataSource]="dataSource"></app-dynamic-com>
</div>
</div>
3. form-design.component.ts組件類定義參數3d
@Component({
selector: 'app-form-design',
templateUrl: './form-design.component.html',
styleUrls: ['./form-design.component.css']
})
export class FormDesignComponent implements OnInit {
dataSource: Array<any> = [];
css=`.myDiv{ font-size:20px}
#div1{color:red}`;
js=` function test(){
alert(111)
}`;
html = `<div class="myDiv">按鈕:<button onclick="test()">查看</button><br/>
<div id="div1">文字</div></div>`;
constructor(private listService: ListService) {
}
ngOnInit() {}
}