在Angular 2中输出组件数组

7

我正在使用Angular 2(和TypeScript)构建一个模态组件,其中包含不同的视图/页面。它不会有选项卡,但概念非常相似。基本上,我正在努力找到一种处理这个问题的方法。

在我的模态组件内部,我想要输出不同的视图/页面。每个页面都应该是一个单独的组件,因为它们没有任何共同的标记。此外,它们将从服务类中获取数据,因此我需要能够为每个视图编写特定的逻辑。

基本上,我想要的是这样的东西:

// Within my modal component's template
<div *ngFor="#view of views">
    // Render view component here
</div>

在这里,views可以是组件的数组。我的首要问题是我不确定如何输出我的视图(组件)的集合。

我应该如何在一个组件中输出多个子组件呢?

此外,我需要一种方法来隐藏和显示这些视图,因为这是它们唯一共同的特点。我考虑给视图添加一个isActive变量,并根据此变量来显示/隐藏它们。将实现ModalView接口或从基类继承以添加该逻辑是否是实现视图组件的不良实践?从我的模态窗口组件中,我希望能够控制显示哪个视图,所以我需要这些视图有这个逻辑的共同点。

希望我的意图已经表达清楚了。解决方案可能很简单,但现在我有点困惑怎么做。如果有代码示例会更加感激!

2个回答

5
你可以创建一个“组件工厂”作为指令,使用DynamicComponentLoader加载适当的组件,根据你从模态框中传递的参数。
<component-factory *ngFor="#view of views" 
    (loaded)="addComponent($event)"
    [name]="view.name" 
    [visible]="view.visible"></component-factory>

@Directive({ selector: 'component-factory' })
class ComponentFactory {
  @Input() name;
  @Input() visible;
  @Output() loaded = new EventEmitter();
  constructor(
    private _dcl: DynamicComponentLoader, 
    private _eref: ElementRef) {

  // import OneCmp, TwoCmp in this file...
  private components: { one: OneCmp, two: TwoCmp }

  ngOnInit() {
    this._dcl.loadNextToLocation(
      this.components[this.name], 
      this._eref)
      // pass values to the loaded components
      // and send it's instance to the parent
      .then((ref: ComponentRef) => {
        ref.instance.visible = this.visible;
        this.loaded.emit(ref.instance)
      });
  }
}

哦,那看起来太棒了,非常感谢!我想,如果我需要进一步与我的视图交互,我可能想将代码从指令中提取出来,并嵌入到模态组件中(或者至少在那里引用工厂),因为这样我可以保留对加载的组件的引用。如果您对此方法有任何反馈,我很乐意听取意见。无论如何,现在我有了一些非常有用的参考代码,所以点赞! - ba0708
我认为该指令更具可重用性。您可以通过@Output()将引用发送回父组件,通过发射(ref: ComponentRef)并在模态框中收集它们。 - Sasxa
太棒了,那是拼图中缺失的一块。非常感谢 - 非常有帮助! - ba0708
有没有不需要使用已废弃的 DynamicComponentLoader 的解决方案? - cocoseis
@cocoseis 这个答案对我帮助很大,而且似乎一直保持着最新状态:https://dev59.com/iFoV5IYBdhLWcg3wY976#36325468 - ccondrup

1

Angular2 动态渲染模板

import { Component, View, DynamicComponentLoader, ElementRef} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser'

@Component({
    selector: 'some-component',
    properties: ['greeting'],
    template: `
    <b>{{ greeting }}</b>
  `
})
class SomeComponent { }




@Component({
    selector: 'app'
})
@View({
    template: `
    <h1>Before container</h1>
    <div #container></div>
    <h2>After container</h2>
  `
})
class App {
    loader: DynamicComponentLoader;
    elementRef: ElementRef;

    constructor(loader: DynamicComponentLoader, elementRef: ElementRef) {
    this.laoder = loader;
    this.elementRef = elementRef;

    // Some async action (maybe ajax response with html in it)
    setTimeout(() => this.renderTemplate(`
      <div>
    <h2>Hello</h2>
    <some-component greeting="Oh, hey"></some-component>
      </div>

完整代码:https://github.com/guyoung/GyPractice-Angular2Advanced/tree/master/apps/dynamically_render_template


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接