typescript Angular:将组件传递给组件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43933783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:32:44  来源:igfitidea点击:

Angular: Pass Component to a Component

angulartypescriptinputnestedcomponents

提问by Draftsman

I have this small gridComponent:

我有这个小 gridComponent:

@Component({
    selector: 'moving-grid',
    templateUrl: './grid.component.html',
    styleUrls: ['./grid.component.css']
})
  export class GridComponent {
     @Input('widgets') extComponents: Array<Component>;
  }

And a second testComponent

和第二个 testComponent

@Component({
  selector: 'test',
  template: `
    <div #content>I say hello<li>i</li><li>u</li><button (click)="test()">click me</button> world</div>
  `
})

export class TestComponent {
  @ViewChild('content') content: HTMLElement;

  getContent() {
    return this.content;
  }
  test() {
    console.log("test");
  }
}

Now I'm trying to pass multiple instances of testComponent to the gridComponent. Therefore I have a third Component which looks like this one:

现在我试图将 testComponent 的多个实例传递给 gridComponent。因此,我有第三个组件,如下所示:

template: `
        <moving-grid [widgets]="[z1,z2]"> 
          <test  class="grid-item-content-001" #z1></test>
          <test  class="grid-item-content-002" #z2></test>
        </moving-grid>
      `

Until this point, everything works like expected. But how can I render the Components from @Input in the gridComponent? My first approach was to declare a @ViewChild in the testComponent and return it with a getContent()-function. But it won't work. Can I use the ng-content directive in some way or is there a better solution?

到目前为止,一切都按预期进行。但是如何从 gridComponent 中的 @Input 渲染组件?我的第一种方法是在 testComponent 中声明一个 @ViewChild 并使用 getContent() 函数返回它。但它不会工作。我可以以某种方式使用 ng-content 指令还是有更好的解决方案?

The GridComponent looks like this. I want to display the templates of a @Input-Component inside one of the black boxes. Is it possible?

GridComponent 看起来像这样。我想在其中一个黑框内显示 @Input-Component 的模板。是否可以?

Moving-Grid Component

移动网格组件

Thanks for any kind of help

感谢您的任何帮助

回答by Poul Kruijt

You should not use an @Inputto pass in the components. You can use @ContentChildrenfor that and an abstract WidgetComponent:

您不应该使用 an@Input来传递组件。你可以使用@ContentChildren它和一个摘要WidgetComponent

@Component({
    selector: 'moving-grid',
    template: `
      <div class="widget-wrapper">
         <ng-container *ngFor="let widget of widgets">
             <!-- use a ngSwitchCase here for different types-->
             <grid-test-widget [widget]="widget" *ngIf="widget.active && widget.type === 'test'"></grid-widget>
         </ng-container>          
      </div>
    `,
    styleUrls: ['./grid.component.css']
})
export class GridComponent implements AfterContentInit {
     @ContentChildren('widget') widgets: WidgetComponent[];

     ngAfterContentInit() {
        //your components will be available here
     }
}

The template of your third component will stay the same, but without the [widgets]and an added #widgetname:

第三个组件的模板将保持不变,但没有[widgets]和 添加的#widget名称:

<moving-grid> 
  <test-widget class="grid-item-content-001" #widget [active]="false"></test>
  <test-widget class="grid-item-content-002" #widget></test>
</moving-grid>

Your TestWidgetComponentwhich will extend an abstract WidgetComponent :

您的TestWidgetComponent这将扩展一个抽象的 WidgetComponent :

@Directive({
  selector: 'test-widget'
})
export class TestWidgetComponent extends WidgetComponent {
    public type: string = 'test';
}

And your WidgetComponent:

还有你的WidgetComponent

@Injectable()
export class WidgetComponent {

   @Input()
   public active: boolean;

   public type: string;

}

And you'll have several grid widgets based on the type of the widget:

您将拥有多个基于小部件类型的网格小部件:

@Component({
  selector: 'grid-test-widget',
  template: `<div #content>I say hello<li>i</li><li>u</li><button (click)="test()">click me</button> world</div>`
})
export class GridTestWidgetComponent{}