繁体   English   中英

使用现有组件和模块动态加载Angular 4模板

[英]Dynamically load Angular 4 template using existing component and module

我正在尝试加载从后端收到的HTML模板。 该模板包括自定义管道,应填充从其他Web服务接收的数据。 这是当前设置的示例。

-app
-/person
--person.module.ts
--person.service.ts
--/person-info
---person-info.component.ts

理想情况下,我想接收模板并在person-info.component.ts中进行设置,因为我在该组件中拥有该HTML的所有必需代码。 我开始按照https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e中说明的步骤进行操作,并提出了以下建议。

person-info.component.ts

import { JitCompilerFactory } from '@angular/compiler';

export function createJitCompiler() {
  return new JitCompilerFactory([{
    useDebug: false,
    useJit: true
  }]).createCompiler();
}

@Component({
  selector: 'person-info',
  template: `<div #vc></div>`,
  styleUrls: ['./person-info.component.css'],
  providers: [
    {provide: Compiler, useFactory: createJitCompiler},
  ]
})
export class PersinInfoComponent implements OnInit {

@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
constructor(
  private route: ActivatedRoute,
  private router: Router,    
  private injector: Injector, 
  private moduleRef: NgModuleRef<any>,
  private compiler: Compiler
)
  ngAfterViewInit() {

this.personService.getPersonTemplate(this.id)
  .then(myTemplate => {  
     const tmpCmp = Component({template: myTemplate})(class{
      });
      const tmpModule = NgModule({declarations: [tmpCmp], imports: [CommonModule]})(class {
      });

      this.compiler.compileModuleAndAllComponentsAsync(tmpModule)
        .then((factories) => {
          console.log('after compiler');
          const f = factories.componentFactories[0];
          const cmpRef = this.vc.createComponent(f);
          cmpRef.instance.name = 'dynamic';
          this.loadData(); // this method just loads data from service
      })
 })
}

这是正在接收的HTML代码的片段

person-info.component.html

<div *ngIf="personDataList">
  <div class="panel panel-default">
    <table class="table customBackground results">
      <tr>
        <th>Add</th>
        <th>Full Name</th>
        <th>Id</th>
        <th>Relationship</th>
      </tr>
      <tr *ngFor="let personData of personDataList; let i = index" [class.disabled-background]="changeRowBackground(personData.id)" >
        <td class="form-group">
          <input [attr.disabled]="changeRowBackground(personData.id) ? true : null"  type="checkbox" name="checkbox" ([ngModel])="personData.add" (change)="onSelectAddBox(i)">
        </td>
        <td>{{personData.fullName}}</td>
        <td>{{personData.id}}</td>
        <td>{{personData.rltnType | keyLookup: relTypeList}}</td>
      </tr>
    </table>
  </div>
</div>

<form *ngIf="selectedPersonData" [formGroup]="personForm" (ngSubmit)="onSubmit()">
  <div class="row row-centered">
    <div class="col-md-3 col-centered">
      <label>Add Date</label><span class="required-text">*</span>
      <input  class="form-control" 
              type="text" 
              [formControl]="dateCtrl"
              [(ngModel)]="selectedPersonData.addDate"
              >
      <div *ngIf="dateCtrl.hasError('required') && dateCtrl.touched" class="alert alert-danger">
        Date is required
      </div>
      <div *ngIf="dateCtrl.hasError('errMsg')" class="alert alert-danger">
        {{dateCtrl.getError('errMsg')}}
      </div>           
    </div>
    <div class="col-md-3 col-centered">
      <label>Reason Code</label><span class="required-text">*</span>
       <select  class="form-control" 
                name="code"
                [formControl]="codeCtrl" 
                [(ngModel)]="selectedPersonData.code"
                >
        <option *ngFor="let currCode of codeList; let i = index" [ngValue]="currCode.key">{{currCode.value}}</option>
      </select>
      <div *ngIf="codeCtrl.hasError('required') && codeCtrl.touched" class="alert alert-danger">
        Code is required
      </div>
    </div>
  </div>
</form>
<p><span class="required-text">*</span>Indicates required field</p>
<span>
  <button type="button" class="btn btn-warning btn-sm" (click)="onCancel()">Cancel</button>
  <button type="submit" class="btn btn-success btn-sm" [disabled]="!personForm.valid || !selectedPersonData" (click)="onSubmit()">Submit</button>
</span>

不幸的是,尝试此方法时遇到问题。 主要具有绑定角度语法。 我收到如下错误。

Can't bind to 'formGroup' since it isn't a known property of 'form'
Can't bind to 'formControl' since it isn't a known property of 'input'

我目前在Angular 4上

@angular/animations: 4.1.3
@angular/common: 4.1.3
@angular/compiler: 4.1.3
@angular/core: 4.1.3
@angular/forms: 4.1.3
@angular/http: 4.1.3
@angular/platform-browser: 4.1.3
@angular/platform-browser-dynamic: 4.1.3
@angular/router: 4.1.3
@angular/cli: 1.2.5
@angular/compiler-cli: 4.1.3
@angular/language-service: 4.1.3

我要完成的总体目标是能够根据用户可能具有的特定安全角色呈现内容 从我所做的研究来看,这似乎是最好的方法,但是如果另一种方法更适合这种情况(即使在较新版本的Angular中也是如此),请随时告诉我。

您只需要将FormsModuleReactiveFormsModule导入到您的自定义模块中:

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

const tmpModule = NgModule({
    declarations: [tmpCmp],
    imports: [..., FormsModule, ReactiveFormsModule]
})(class {});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM