LP#1775466 Dynamic component partial retraction
authorBill Erickson <berickxx@gmail.com>
Thu, 14 Jun 2018 14:30:53 +0000 (10:30 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 14 Jun 2018 14:30:55 +0000 (10:30 -0400)
Dynamic component as-is only works in JIT compliation mode.  Leaving for
reference, but commenting out any uses.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/common.module.ts
Open-ILS/src/eg2/src/app/share/dynamic-component/dynamic.component.ts [deleted file]
Open-ILS/src/eg2/src/app/share/print/print.component.html
Open-ILS/src/eg2/src/app/share/print/print.component.ts
Open-ILS/src/eg2/src/app/share/print/print.service.ts
Open-ILS/src/eg2/src/app/share/util/dynamic.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/common.module.ts
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts

index e04e003..89fef35 100644 (file)
@@ -6,6 +6,7 @@ import {NgModule, ModuleWithProviders} from '@angular/core';
 import {RouterModule} from '@angular/router';
 import {FormsModule} from '@angular/forms';
 import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
+import {HttpClientModule} from '@angular/common/http';
 
 import {EventService} from '@eg/core/event.service';
 import {StoreService} from '@eg/core/store.service';
@@ -26,30 +27,38 @@ import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 import {PromptDialogComponent} from '@eg/share/dialog/prompt.component';
 import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
 
+// DynamicComponent only works in JIT compilation mode.
+// Leaving for now as reference while considering alternatives
+import {DynamicComponent} from '@eg/share/util/dynamic.component';
+
 @NgModule({
   declarations: [
     PrintComponent,
     DialogComponent,
     ConfirmDialogComponent,
     PromptDialogComponent,
-    ProgressDialogComponent
+    ProgressDialogComponent,
+    DynamicComponent
   ],
   imports: [
     CommonModule,
     FormsModule,
     RouterModule,
+    HttpClientModule,
     NgbModule
   ],
   exports: [
     CommonModule,
     RouterModule,
+    HttpClientModule,
     NgbModule,
     FormsModule,
     PrintComponent,
     DialogComponent,
     ConfirmDialogComponent,
     PromptDialogComponent,
-    ProgressDialogComponent
+    ProgressDialogComponent,
+    DynamicComponent
   ]
 })
 
diff --git a/Open-ILS/src/eg2/src/app/share/dynamic-component/dynamic.component.ts b/Open-ILS/src/eg2/src/app/share/dynamic-component/dynamic.component.ts
deleted file mode 100644 (file)
index 35723a8..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-import {Component, OnInit, ViewChild, Input, Output} from '@angular/core';
-import {Compiler, ViewContainerRef, NgModule, EventEmitter} 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.
- * 
- * Content text or URL values may be provided as Inputs or passed
- * directly to component build* methods.
- */
-
-@Component({
-  selector: 'eg-dynamic-component',
-  template: '<ng-container #container></ng-container>'
-})
-
-export class DynamicComponent implements OnInit {
-
-    @ViewChild('container', {read: ViewContainerRef})
-    private container: ViewContainerRef;
-
-    @Input() content: string;
-    @Input() contentUrl: string;
-    @Input() contextData: any;
-
-    // Emits true if the content was render-able, false otherwise
-    @Output() onComplete: EventEmitter<boolean>;
-
-    constructor(
-        private compiler: Compiler,
-        private http: HttpClient
-    ) {
-        this.onComplete = new EventEmitter<boolean>();
-    }
-
-    ngOnInit() {
-        if (this.contentUrl) {
-            this.buildFromUrl(this.contentUrl, this.contextData);
-        } else if (this.content) {
-            this.buildFromString(this.content, this.contextData);
-        }
-    }
-
-    buildFromString(template: string, context: any = {}) {
-        try {
-            this.addComponent(template, context);
-        } catch (err) {
-            console.error(`Error rendering dynamic content: ${err}`);
-            this.onComplete.emit(false);
-            return;
-        }
-
-        this.onComplete.emit(true);
-    }
-
-    // Returns a promise which resolves if the requested URL
-    // was found and was render-able, 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}`);
-                try {
-                    this.addComponent(html, context);
-                } catch (err) {
-                    const msg = `Error rendering dynamic content: ${url}`;
-                    console.error(msg);
-                    this.onComplete.emit(false);
-                    return Promise.reject(msg);
-                }
-                this.onComplete.emit(true);
-            },
-            notFound => {
-                console.debug(
-                    `Unable to fetch dynamic component URL: ${url}`, notFound);    
-                this.onComplete.emit(false);
-            }
-        )
-    }
-
-    // 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();
-    }
-
-}
-
index bc47c38..08e2cc6 100644 (file)
@@ -1,5 +1,18 @@
 
 <div id='eg-print-container'>
-    <ng-container *ngTemplateOutlet="template; context:context"></ng-container>
+  <ng-container *ngIf="template">
+    <!-- refs to compiled templates are inserted inline -->
+    <ng-container *ngTemplateOutlet="template; context:context">
+    </ng-container>
+  </ng-container>
+
+  <!-- This component only works with JIT compilation 
+
+  <ng-container *ngIf="templateString">
+    <eg-dynamic-component [content]="templateString" 
+      [contextData]="this.context.$implicit">
+    </eg-dynamic-component>
+  </ng-container>
+  -->
 </div>
 
index 0496f0c..0270a8b 100644 (file)
@@ -1,4 +1,6 @@
 import {Component, OnInit, TemplateRef, ElementRef} from '@angular/core';
+// See dynamic.component for details on why it's commented out.
+//import {DynamicComponent} from '@eg/share/util/dynamic.component';
 import {PrintService, PrintRequest} from './print.service';
 
 @Component({
@@ -9,6 +11,7 @@ import {PrintService, PrintRequest} from './print.service';
 export class PrintComponent implements OnInit {
 
     template: TemplateRef<any>;
+    //templateString: string;
     context: any;
 
     constructor(
@@ -23,6 +26,7 @@ export class PrintComponent implements OnInit {
 
     handlePrintRequest(printReq: PrintRequest) {
         this.template = printReq.template;
+        //this.templateString = printReq.templateString;
         this.context = {$implicit: printReq.contextData};
 
         // Give the template a chance to render inline before printing
index 4c9914f..3460d8a 100644 (file)
@@ -2,6 +2,7 @@ import {Injectable, EventEmitter, TemplateRef} from '@angular/core';
 
 export interface PrintRequest {
     template: TemplateRef<any>;
+    //templateString?: string,
     contextData: any;
     printContext: string;
 }
diff --git a/Open-ILS/src/eg2/src/app/share/util/dynamic.component.ts b/Open-ILS/src/eg2/src/app/share/util/dynamic.component.ts
new file mode 100644 (file)
index 0000000..2f67671
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * WARNING: This component only works when using the JIT compiler.
+ * Compiling --aot prevents the JitCompiler from working.
+ */
+import {Component, OnInit, ViewChild, Input, Output, TemplateRef} from '@angular/core';
+import {Compiler, ViewContainerRef, NgModule, EventEmitter} 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.
+ * 
+ * Content text or URL values may be provided as Inputs or passed
+ * directly to component build* methods.
+ */
+
+@Component({
+  selector: 'eg-dynamic-component',
+  template: '<ng-container #container></ng-container>'
+})
+
+export class DynamicComponent implements OnInit {
+
+    @ViewChild('container', {read: ViewContainerRef})
+    private container: ViewContainerRef;
+
+    @Input() content: string;
+    @Input() contentUrl: string;
+    @Input() contextData: any;
+
+    // Emits true if the content was render-able, false otherwise
+    @Output() onComplete: EventEmitter<boolean>;
+
+    constructor(
+        private compiler: Compiler,
+        private http: HttpClient
+    ) {
+        console.warn("DynamicComponent only works in JIT compilation mode");
+        this.onComplete = new EventEmitter<boolean>();
+    }
+
+    ngOnInit() {
+        if (this.contentUrl) {
+            this.buildFromUrl(this.contentUrl, this.contextData);
+        } else if (this.content) {
+            this.buildFromString(this.content, this.contextData);
+        }
+    }
+
+    buildFromString(template: string, context: any = {}) {
+        try {
+            this.addComponent(template, context);
+        } catch (err) {
+            console.error(`Error rendering dynamic content: ${err}`);
+            this.onComplete.emit(false);
+            return;
+        }
+
+        this.onComplete.emit(true);
+    }
+
+    // Returns a promise which resolves if the requested URL
+    // was found and was render-able, 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}`);
+                try {
+                    this.addComponent(html, context);
+                } catch (err) {
+                    const msg = `Error rendering dynamic content: ${url}`;
+                    console.error(msg);
+                    this.onComplete.emit(false);
+                    return Promise.reject(msg);
+                }
+                this.onComplete.emit(true);
+            },
+            notFound => {
+                console.debug(
+                    `Unable to fetch dynamic component URL: ${url}`, notFound);    
+                this.onComplete.emit(false);
+            }
+        )
+    }
+
+    // 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();
+    }
+
+}
+
index 60d23d6..2dfbb3c 100644 (file)
@@ -1,5 +1,4 @@
 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';
@@ -13,7 +12,6 @@ import {StringComponent} from '@eg/share/string/string.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.
@@ -29,15 +27,12 @@ import {DynamicComponent} from '@eg/share/dynamic-component/dynamic.component';
     StringComponent,
     OpChangeComponent,
     FmRecordEditorComponent,
-    DateSelectComponent,
-    DynamicComponent
+    DateSelectComponent
   ],
   imports: [
-    HttpClientModule,
     EgCommonModule
   ],
   exports: [
-    HttpClientModule,
     EgCommonModule,
     StaffBannerComponent,
     OrgSelectComponent,
@@ -47,8 +42,7 @@ import {DynamicComponent} from '@eg/share/dynamic-component/dynamic.component';
     StringComponent,
     OpChangeComponent,
     FmRecordEditorComponent,
-    DateSelectComponent,
-    DynamicComponent
+    DateSelectComponent
   ]
 })
 
index 6fc4afe..fda77a4 100644 (file)
 <button class="btn btn-secondary" (click)="doPrint()">Test Print</button>
 <ng-template #printTemplate let-context>Hello, {{context.world}}!</ng-template>
 
+
+<!--  Dynamic components only work with the JIT compiler.
+      Leaving globally disabled for now.
+<br/>
+<button class="btn btn-secondary" (click)="doDynamicPrint()">Test DynamicPrint</button>
+
 <br/><br/>
 
-<!-- dynamic template/component example -->
 <b>Dynamic content: </b>
 <eg-dynamic-component #dynamic></eg-dynamic-component>
 
 <br/>
-<!--
-<b>Dynamic content via URL: </b>
-<eg-dynamic-component #dynamicUrl></eg-dynamic-component>
-<br/>
--->
 
 <b>Dynamic Complent via URL Inline</b>
 <eg-dynamic-component 
@@ -94,7 +94,7 @@
 <div *ngIf="renderLocal">
   <b>fall through local template: hello {{world}}</b>
 </div>
-
+-->
 
 <br/><br/>
 
index bedadd1..1dc600f 100644 (file)
@@ -12,7 +12,7 @@ import {PcrudService} from '@eg/core/pcrud.service';
 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';
+//import {DynamicComponent} from '@eg/share/util/dynamic.component';
 
 @Component({
   templateUrl: 'sandbox.component.html'
@@ -28,8 +28,8 @@ export class SandboxComponent implements OnInit {
     @ViewChild('printTemplate')
     private printTemplate: TemplateRef<any>;
 
-    @ViewChild('dynamic') private dynamic: DynamicComponent;
-    @ViewChild('dynamicUrl') private dynamicUrl: DynamicComponent;
+    //@ViewChild('dynamic') private dynamic: DynamicComponent;
+    //@ViewChild('dynamicUrl') private dynamicUrl: DynamicComponent;
 
     // @ViewChild('helloStr') private helloStr: StringComponent;
 
@@ -39,6 +39,8 @@ export class SandboxComponent implements OnInit {
     world = 'world'; // for local template version
     btGridTestContext: any = {hello : this.world};
 
+    renderLocal = false;
+
     testDate: any;
 
     testStr: string;
@@ -72,10 +74,10 @@ export class SandboxComponent implements OnInit {
             });
         };
 
+        /*
         this.dynamic.buildFromString(
             '<b>HELLO {{world}}</b>', {world: this.world});
 
-        /*
         // Assumes a file on the server at this URL
         this.dynamicUrl.buildFromUrl(
             '/test-template.html', {world: this.world});
@@ -90,6 +92,16 @@ export class SandboxComponent implements OnInit {
         });
     }
 
+    doDynamicPrint() {
+        /*
+        this.printer.print({
+            templateString: '<b>DYNAMIC HELLO {{world}}</b>',
+            contextData: {world : this.world},
+            printContext: 'default'
+        });
+        */
+    }
+
     changeDate(date) {
         console.log('HERE WITH ' + date);
         this.testDate = date;