mat-grid-list 在其自己的实现中使用内容投影,因此它需要能够查询其投影内容。尝试添加另一个级别的内容投影使得这是不可能的,因为 mat-grid-tile 实际上不是由列表投影的,而是由您的组件投影的。
简短的回答:这行不通。
可能有一种方法可以实现您的目标,但内容投影不是方法。如果你稍微澄清一下你的意图,我也许能帮上忙。不过,您可能需要使用模板。
这是一个简单的情况:围绕 mat-grid-list 编写一个包装器,该包装器接受数据数组作为输入,您可以使用 ngFor 对其进行迭代以创建图块
@Component({
selector: 'my-grid',
templateUrl: './my-grid.html'
})
export class MyGrid {
@Input() data: string[];
}
<mat-grid-list>
<mat-grid-tile *ngFor="let d of data">{{d}}</mat-grid-tile>
</mat-grid-list>
这为 mat-grid-list 提供了一个可重用的包装器,为您抽象了一些内容。但是,如果您的网格内容比字符串(可能)更复杂或者每次使用都需要自定义模板,那么这就不太好了。在这种情况下,您需要一种更精细的方法,使用模板和指令:
@Directive({
selector: 'gridTemplate'
})
export class GridTemplate {
@Input() key: string;
constructor(private elementRef: ElementRef, public template: TemplateRef<any>) {}
}
该指令将识别您的自定义模板,然后在网格列表中,您可以使用这些模板来填充图块
@Component({
selector: 'my-grid',
templateUrl: './my-grid.html'
})
export class MyGrid implements AfterContentInit {
//structure the data so it can be assigned to a template by key
@Input() data: {templateKey:string, data: any}[];
//use content children to find projected templates
@ContentChildren(GridTemplate)
gridTemplates: QueryList<GridTemplate>;
gridTemplateMap: {[key:string]: TemplateRef<any>} = {};
ngAfterContentInit() {
//store queried templates in map for use in template
this.gridTemplates.forEach(t => this.gridTemplateMap[t.key] = t.template);
}
}
<ng-template #defaultGridTemp let-d="data">{{d}}</ng-template>
<mat-grid-list>
<mat-grid-tile *ngFor="let d of data">
<!-- here we use the template map to place the correct templates or use a default -->
<!-- we also feed the data property as context into the template -->
<ng-container [ngTemplateOutlet]="(gridTemplateMap[d.templateKey] || defaultGridTemp)"
[ngTemplateOutletContext]="{ data: d.data }" ></ng-container>
</mat-grid-tile>
</mat-grid-list>
那么你的组件的用法是这样的:
@Component({...})
export class MyComponent {
data = [
{ templateKey:'MyKey1', data: {message: 'Projected Message', number: 1} },
{ templateKey:'MyKey2', data: {whatever: 'Message', youWant: 'to place'} }
];
}
<my-grid [data]="data">
<ng-template gridTemplate key="MyKey1" let-d="data">
<div>{{d.message}}</div>
<div>{{d.number}}</div>
<div>Any other arbitrary content</div>
</ng-template>
<ng-template gridTemplate key="MyKey2" let-d="data">
<div>{{d.whatever}}</div>
<div>{{d.youWant}}</div>
<div>Any other arbitrary content</div>
</ng-template>
</my-grid>
通过这种方法,您可以将任何可重用逻辑添加到网格组件内所需的 mat-grid-list 中,但仍保持为网格提供自定义模板的灵活性。缺点是您必须采取额外的步骤来构建数据才能利用此方法。