Angular:将组件传递给组件

时间:2017-05-12 09:11:18

标签: angular typescript input nested components

我有这个小的gridComponent:

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

第二个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");
  }
}

现在我正在尝试将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>
      `

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

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

Moving-Grid Component

感谢您提供任何帮助

1 个答案:

答案 0 :(得分:8)

您不应使用@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
     }
}

第三个组件的模板将保持不变,但没有[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>

你的TestWidgetComponent将扩展抽象的WidgetComponent:

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

您的WidgetComponent

@Injectable()
export class WidgetComponent {

   @Input()
   public active: boolean;

   public type: string;

}

根据窗口小部件的类型,您将拥有多个网格小部件:

@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{}