gpt4 book ai didi

javascript - Angular - mat-grid-list 不显示 传递的子项

转载 作者:行者123 更新时间:2023-11-29 23:18:20 25 4
gpt4 key购买 nike

我正在使用 Angular Material 设计组件并想创建一个自定义网格列表组件。该组件将根据其大小调整网格列表列的数量。组件模板如下所示:

<mat-grid-list [cols]="adaptiveCols">
<ng-content></ng-content>
</mat-grid-list>

组件将这样使用:

<my-grid>
<mat-grid-tile>tile_content</mat-grid-tile>
<mat-grid-tile>tile_content</mat-grid-tile>
<mat-grid-tile>tile_content</mat-grid-tile>
</my-grid>

所以你会认为这会显示一个 <mat-grid-list>与 3 <mat-grid-tile> s 在其中,生成的 DOM 将包含这些元素。但是您看不到图 block 及其内容。

向网格列表添加更多图 block 并使用固定 rowHeight不影响 height - 网格列表的属性(据我所知,网格列表根据图 block 的数量和 col-/rowspan 计算其高度)。这让你认为网格列表没有“看到” <mat-grid-tile> - children 。看着 source code of the grid-list并在 _layoutTiles() 上设置断点在这种方法中证实了这一点 this._tiles是空的。
我的猜测是 Angular ContentChildren -annotation ( here ) 在第一个代码片段中找不到 tile-children 因为它只适用于 DOM 的第一层,而第一层我们只有 <ng-content> .

想要的结果很明确,我希望能够使用自定义的网格列表组件,给它一些 child 并使用它的功能。但出于某种原因,angular 不希望我成功,或者我还有东西要学。

我正在使用 angular 6.1 并使用 official docs 安装了 Material 组件.

最佳答案

mat-grid-list 在它自己的实现中使用内容投影,因此它需要能够查询它的投影内容。尝试添加另一个级别的内容投影会使这成为不可能,因为 mat-grid-tile 实际上不是由列表投影的,而是由您的组件投影的。

如此简短的回答:这行不通。

可能有一种方法可以实现您的目标,但内容投影不是这种方法。如果你稍微澄清一下你的意图,我也许能帮上忙。不过,您可能需要使用模板。

这是一个简单的例子:围绕 mat-grid-list 编写一个包装器,它接受一个数据数组作为输入,您可以使用 ngFor 迭代它来创建图 block

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

此指令将识别您的自定义模板,然后在您的网格列表中,您可以使用这些模板来填充图 block

@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,但仍保持为网格提供自定义模板的灵 active 。缺点是您必须采取额外的步骤来构建数据才能利用这种方法。

关于javascript - Angular - mat-grid-list 不显示 <ng-content> 传递的子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51801295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com