七夜之恋 發表於 2019-12-30 13:09:00

Angular动态编译HTML模版

<p>问题:需要打印的模版特别多,而且各不相同,可能需要经常改动,如果在前端进行单独创建组件的方式每次添加模版修改模版都要重新发布版本。</p>
<p>解决方式:通过把模版HTML保存到数据库的方式,根据调用打印的传参获取不同的打印模版</p>
<p>oracle中nvarchar最多存4000个字符数量&nbsp; &nbsp; &nbsp;NCLOB最大存储大小为4gb</p>
<p>&nbsp;</p>
<p>通过,只能渲染模版中的html语法和样式,模版中的angular模版无法这些无法进行解析。这种方式只能渲染文本内容</p>
<p>&nbsp;</p>
<p>通过ComponentFactoryResolver,这个对象可以接受一个组件类型创建一个组件实例。这种方式组件在前端需要存在</p>
<p>&nbsp;</p>
<p>通过下面这种方式来动态编译HTML模版</p>
<div class="cnblogs_code">
<pre>import {Compiler, Component, ComponentRef, Injector, NgModule, NgModuleRef, ViewChild, ViewContainerRef} <span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">@angular/core</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
import {CommonModule} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">@angular/common</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
import {RouterModule} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">@angular/router</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
import { HelloComponent } </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./hello.component</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;

@Component({
selector: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">dynamic-template</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
template: `</span>&lt;h2&gt;Stuff bellow will <span style="color: rgba(0, 0, 255, 1)">get</span> dynamically created and injected&lt;h2&gt;
          &lt;div #vc&gt;&lt;/div&gt;<span style="color: rgba(0, 0, 0, 1)">`
})
export </span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> DynamicTemplateComponent {
@ViewChild(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">vc</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, {read: ViewContainerRef}) vc: ViewContainerRef;

</span><span style="color: rgba(0, 0, 255, 1)">private</span> cmpRef: ComponentRef&lt;any&gt;<span style="color: rgba(0, 0, 0, 1)">;

constructor(</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> compiler: Compiler,
            </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> injector: Injector,
            </span><span style="color: rgba(0, 0, 255, 1)">private</span> moduleRef: NgModuleRef&lt;any&gt;<span style="color: rgba(0, 0, 0, 1)">,
) {}

ngAfterViewInit() {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.createComponentFromRaw(`&lt;div style=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">border: 1px solid blue; margin: 5px; padding: 5px</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;div&gt;Start Raw Component ... &lt;/div&gt;
    &lt;h5&gt;Binding value: {{data.some}}&lt;/h5&gt;
    &lt;span *ngIf=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">getX() === 'X'</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;Use *ngIf: {{getX()}} &lt;/span&gt;
    &lt;/div&gt;<span style="color: rgba(0, 0, 0, 1)">`);
}

</span><span style="color: rgba(0, 0, 255, 1)">private</span> createComponentFromRaw(template: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">) {
    </span><span style="color: rgba(0, 0, 255, 1)">const</span> styles =<span style="color: rgba(0, 0, 0, 1)"> [];
    function TmpCmpConstructor() {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">需要给当前创建的模版传递的数据</span>
      <span style="color: rgba(0, 0, 255, 1)">this</span>.data = { some: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> };
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">需要给当前创建的模版传递的方法</span>
      <span style="color: rgba(0, 0, 255, 1)">this</span>.getX = () =&gt; <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">X</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">const</span> tmpCmp = Component({ template, styles })(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> TmpCmpConstructor().constructor);

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Now, also create a dynamic module.</span>
    <span style="color: rgba(0, 0, 255, 1)">const</span> tmpModule =<span style="color: rgba(0, 0, 0, 1)"> NgModule({
      imports: ,
      declarations: ,
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如果这个html模版中用到了其他组件需要把这个组件也传递进去
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> declarations: ,
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> providers: [] - e.g. if your dynamic component needs any service, provide it here.</span>
    })(<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> {});

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Now compile this module and component, and inject it into that #vc in your current component template.</span>
    <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.compiler.compileModuleAndAllComponentsAsync(tmpModule)
      .then((factories) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
          </span><span style="color: rgba(0, 0, 255, 1)">const</span> f = factories.componentFactories[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">];
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.cmpRef = f.create(<span style="color: rgba(0, 0, 255, 1)">this</span>.injector, [], <span style="color: rgba(0, 0, 255, 1)">null</span>, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.moduleRef);
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.cmpRef.instance.name = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my-dynamic-component</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.vc.insert(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.cmpRef.hostView);
      });
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Cleanup properly. You can add more cleanup-related stuff here.</span>
<span style="color: rgba(0, 0, 0, 1)">ngOnDestroy() {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.cmpRef) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.cmpRef.destroy();
    }
}
}</span></pre>
</div>
<p>&nbsp;</p>
<p>资料</p>
<p>https://stackblitz.com/edit/dynamic-raw-template?file=src%2Fapp%2Fdynamic-template.component.ts</p>
<p>https://stackoverflow.com/questions/48028676/compile-dynamic-html-in-angular-4-5-something-similar-to-compile-in-angular-js</p><br><br>
来源:https://www.cnblogs.com/jiangchengbiao/p/12119208.html
頁: [1]
查看完整版本: Angular动态编译HTML模版