【问题标题】:Outputting array of components in Angular 2在Angular 2中输出组件数组
【发布时间】:2016-02-22 19:55:36
【问题描述】:

我正在 Angular 2(和 TypeScript)中构建一个模式组件,它将具有不同的视图/页面。它没有标签,但概念非常相似。基本上我正在努力寻找一种方法来做到这一点。

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

基本上我想要的是这样的:

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

例如,views 可以是一个组件数组。我的第一个也是主要的问题是我不确定如何输出我的视图(组件)的集合。

如何输出另一个组件中的组件集合?

另外,我需要一种隐藏和显示视图的方法,这是视图唯一的共同点。我正在考虑在视图中添加一个isActive 变量并基于此显示/隐藏它们。视图组件实现ModalView 接口或从基类扩展以添加此逻辑是否是不好的做法?从我的模态组件中,我希望能够控制显示哪个视图,因此我需要这些视图具有共同的逻辑。

我希望很清楚我想要做什么。解决方案可能很简单,但现在我对如何去做有点困惑。一个代码示例将不胜感激!

【问题讨论】:

    标签: angular


    【解决方案1】:

    您可以创建一个“组件工厂”作为使用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)
          });
      }
    }
    

    【讨论】:

    • 哦,看起来很棒,非常感谢!我在想,如果我需要与我的视图进一步交互,我可能想将代码从指令中提取出来并将该逻辑嵌入到模态组件中(或者至少引用那里的工厂),因为这样我就可以保留引用到加载的组件。如果您对这种方法有任何反馈,我很想听听。不过,现在我有一些非常有用的参考代码,请点赞!
    • 我认为该指令会更可重用。您可以通过@Output() 将引用发送回父组件,方法是发出(ref: ComponentRef) 并在模态中收集它们。
    • 超级,这是拼图中缺失的部分。非常感谢 - 非常有帮助!
    • 没有不推荐使用的DynamicComponentLoader的任何解决方案?
    • @cocoseis 这个答案对我帮助很大,而且似乎保持最新:stackoverflow.com/a/36325468/504075
    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 2019-07-29
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 2017-12-28
      • 2018-03-11
      相关资源
      最近更新 更多