【问题标题】:Angular 7 - Insert new dynamic component into existing moduleAngular 7 - 将新的动态组件插入现有模块
【发布时间】:2019-03-03 12:44:17
【问题描述】:

我对 Angular 还很陌生,但我仍然不明白有些事情是如何工作的。
我正在尝试从 angularJS 模拟 $compile

是否可以将动态创建的组件注入现有模块?例如,将其注入 AppModule,然后即时重新编译所有内容......或者,获取由其他模块(即 AppModule)导入的模块列表

这就是我所拥有的:

@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
private comp: ComponentRef<any>;

private createComponentFromTemplate(template: string, modules: any = []) {
  let this_ = this;
  @Component({
    selector: 'some-tpl',
    template: template
  })
  class TmpComponent {
  }


  @NgModule({
    imports: modules, //here is the problem
    declarations: [
      TmpComponent
    ],
    exports: [
      TmpComponent
    ]
  })
  class TmpModule {
  }

  let mod = this.compiler.compileModuleAndAllComponentsSync(TmpModule);
  let factory = mod.componentFactories.find((c) => c.componentType === TmpComponent);
  this.comp = this.vc.createComponent(factory, 0, this.injector);
  //dynamic component is later destroyed
}

问题:
这完全没问题,但 我想避免生成单独的模块。 “模板”字符串包含的 HTML 代码可以包含任何内容,如果我们在模板中使用其他一些组件/指令,这可能会产生很大的问题。这个问题通过引入“模块”来解决,模块数组应该包含所有需要的模块,以便正确编译新组件

我需要这个,以便启用动态数据处理:
数据通过 REST 服务从数据库中获取
根据用于获取它的数据类型和服务,执行不同的处理(即将电子邮件转换为有效的电子邮件链接,在表格中显示对象列表等)

提前致谢

【问题讨论】:

  • 我认为有一个更简单的方法。为什么不创建一个动态组件并简单地通过服务传递条件、订阅并进行相应的验证?
  • @francojay 请举例说明
  • 仍在试图理解为什么您需要一个处理许多不同功能的组件。我会根据功能分离组件,然后将该组件放入您想要的任何模块中。当您发出 API 请求时,就是在您确定要使用的组件以及要传递给它的数据时。重要的是您的架构尽可能模块化,允许可扩展性
  • @francojay 此类组件的主要目的是在表格中显示获得的值。有时,数字应该显示为货币,而在其他一些情况下,数字是内部用户 ID。这两个值都应在 UI 上正确显示 - 货币为 $value,用户 ID 作为指向用户个人资料页面的链接。这些只是一些基本的例子。用例多种多样,我想添加新的“处理功能”,而不必重构/编写一堆代码来完成一个简单的任务,比如那些描述的 P.S.表也​​是动态生成的(通过从另一个 API 获取元数据)

标签: angular angular7


【解决方案1】:

所以我的思考过程是有两种方法可以做到这一点。我会放弃你这样做的方式,而是有条件地验证自定义组件中的数据。一种方法是使用事件发射器并通过组件传递数据:

使用动态组件的页面

<dynamic-component [settings]="{ type: 'customType', params: { number: 1 } }"></dynamic-component>

动态组件

@Component({
  selector: 'dynamic-component',
  templateUrl: './dynamic-component.html',
  styleUrls: ['./dynamic-component.style.scss'],
})
export class DynamicComponent implements OnInit {
  @Input()
  settings: any

constructor() {     
  if (this.settings.type === 'customType') {
     // Handle conditional data
    }
  }

另一种方式是处理服务之间的数据。

服务

@Injectable()
export class SharedService {
sharedData: BehaviorSubject<any> = new BehaviorSubject<any>(null)
  constructor() {}
}

要从(任何)页面传递数据,请将服务注入构造函数并在行为主题上调用 .next。

constructor(private sharedService: SharedService) {
  sharedService.sharedData.next({ type: 'customType', otherParam: 'foo' })
}

然后订阅数据,并进行相应的验证

动态组件

@AutoUnsubscribe()
@Component({
  selector: 'dynamic-component',
  templateUrl: './dynamic-component.html',
  styleUrls: ['./dynamic-component.style.scss'],
})
export class DynamicComponent implements OnInit, OnDestroy {

// Subscriptions
sharedSub$: Subscription
constructor(private sharedService: SharedService) {     
  this.sharedSub$ = sharedService.sharedData.subscribe((data) => {
if (data.type === 'customType') {
   // Now you have the conditional data
}
  })

 ngOnDestroy() {}
}

@AutoUnsubscribe 只是我的一个建议,用于处理内存和防止泄漏。

【讨论】:

    猜你喜欢
    • 2019-10-30
    • 2019-06-09
    • 2019-02-03
    • 1970-01-01
    • 2018-11-03
    • 2019-12-08
    • 2019-10-08
    • 2017-11-20
    • 2020-03-18
    相关资源
    最近更新 更多