--- /dev/null
+import {Component, OnInit, ViewChild, Input} from '@angular/core';
+import {Compiler, ViewContainerRef, NgModule} from '@angular/core';
+import {HttpClient} from '@angular/common/http';
+
+/**
+ * Render HTML content derived from a string or a URL path,
+ * interpolating the provided context data along the way.
+ */
+
+@Component({
+ selector: 'eg-dynamic-component',
+ template: '<ng-container #container></ng-container>'
+})
+
+export class DynamicComponent implements OnInit {
+
+ @ViewChild('container', {read: ViewContainerRef})
+ private container: ViewContainerRef;
+
+ constructor(
+ private compiler: Compiler,
+ private http: HttpClient
+ ) {}
+
+ ngOnInit() {
+ }
+
+ buildFromString(template: string, context: any = {}) {
+ this.addComponent(template, context);
+ }
+
+ // Returns a promise which resolves if the requested URL
+ // was found, rejected otherwise.
+ buildFromUrl(url: string, context: any = {}): Promise<void> {
+ return this.http.get(url, {responseType: 'text'}).toPromise()
+ .then(
+ html => {
+ console.debug(`Loaded dynamic content from: ${url}`);
+ this.addComponent(html, context);
+ },
+ notFound => {
+ console.debug(
+ `Unable to fetch dynamic component URL: ${url}`, notFound);
+ }
+ )
+ }
+
+ // Method below taken practically verbatim from
+ // https://stackoverflow.com/a/39507831
+ private addComponent(template: string, context: any) {
+ @Component({template}) class TemplateComponent {}
+ @NgModule({declarations: [TemplateComponent]}) class TemplateModule {}
+
+ const mod =
+ this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
+
+ const factory = mod.componentFactories.find((comp) =>
+ comp.componentType === TemplateComponent
+ );
+
+ const component = this.container.createComponent(factory);
+ Object.assign(component.instance, context);
+ // If context changes at a later stage, the change detection
+ // may need to be triggered manually:
+ // component.changeDetectorRef.detectChanges();
+ }
+
+}
+
import {NgModule, ModuleWithProviders} from '@angular/core';
+import {HttpClientModule} from '@angular/common/http';
import {EgCommonModule} from '@eg/common.module';
import {StaffBannerComponent} from './share/staff-banner.component';
import {OrgSelectComponent} from '@eg/share/org-select/org-select.component';
import {StringService} from '@eg/share/string/string.service';
import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
import {DateSelectComponent} from '@eg/share/date-select/date-select.component';
+import {DynamicComponent} from '@eg/share/dynamic-component/dynamic.component';
/**
* Imports the EG common modules and adds modules common to all staff UI's.
StringComponent,
OpChangeComponent,
FmRecordEditorComponent,
- DateSelectComponent
+ DateSelectComponent,
+ DynamicComponent
],
imports: [
+ HttpClientModule,
EgCommonModule
],
exports: [
+ HttpClientModule,
EgCommonModule,
StaffBannerComponent,
OrgSelectComponent,
StringComponent,
OpChangeComponent,
FmRecordEditorComponent,
- DateSelectComponent
+ DateSelectComponent,
+ DynamicComponent
]
})
<button class="btn btn-secondary" (click)="doPrint()">Test Print</button>
<ng-template #printTemplate let-context>Hello, {{context.world}}!</ng-template>
+<br/><br/>
+
+<!-- dynamic template/component example -->
+<b>Dynamic content: </b>
+<eg-dynamic-component #dynamic></eg-dynamic-component>
+
+<b>Dynamic content via URL: </b>
+<eg-dynamic-component #dynamicUrl></eg-dynamic-component>
+
+
+<br/><br/>
<!-- grid stuff -->
<ng-template #cellTmpl let-row="row" let-col="col" let-userContext="userContext">
import {Pager} from '@eg/share/util/pager';
import {DateSelectComponent} from '@eg/share/date-select/date-select.component';
import {PrintService} from '@eg/share/print/print.service';
+import {DynamicComponent} from '@eg/share/dynamic-component/dynamic.component';
@Component({
templateUrl: 'sandbox.component.html'
@ViewChild('printTemplate')
private printTemplate: TemplateRef<any>;
+ @ViewChild('dynamic') private dynamic: DynamicComponent;
+ @ViewChild('dynamicUrl') private dynamicUrl: DynamicComponent;
+
// @ViewChild('helloStr') private helloStr: StringComponent;
gridDataSource: GridDataSource = new GridDataSource();
order_by: {cbt: 'name'}
});
};
+
+ this.dynamic.buildFromString(
+ '<b>HELLO {{world}}</b>', {world: 'world'});
+
+ /*
+ // Assumes a file on the server at this URL
+ this.dynamicUrl.buildFromUrl(
+ '/test-template.html', {world: 'world'});
+ */
}
doPrint() {
}
}
+