在 CSS 网格布局中使用 *ngFor 不希望地在一列中显示所有内容
Posted
技术标签:
【中文标题】在 CSS 网格布局中使用 *ngFor 不希望地在一列中显示所有内容【英文标题】:Using *ngFor in CSS Grid Layout Undesirably Displaying Everything in One Column 【发布时间】:2018-02-21 05:49:34 【问题描述】:总的来说,我是编程和网络开发的新手。我正在制作个人网站。
我想将框放在一个有 4 列的网格中,类似于您在此处看到的:https://devpost.com/software/search?query=is%3Afeatured
这些框中的每一个都代表一个对象,我希望能够在框内显示一些数据,而当您单击框时,将其余数据显示在弹出对话框中。
我一直在玩 CSS 网格布局,现在它变得很流行(强烈推荐这个视频:https://www.youtube.com/watch?v=7kVeCqQCxlk)。
当我在包装器 div 中对一堆 div 元素进行硬编码时,具有 4 列的东西会起作用。但是,每当我在包含我的数据数组的包装器上使用 *ngFor 并将每次迭代中的数据输入到内部 div 元素时,网格布局都会被破坏,将所有内容放入一列中。
当我使用多个 div 元素(此处为 item2)手动输入数据时,它会按需要工作:
.wrapper
margin-left: 1em;
margin-right: 1em;
display: grid;
grid-template-rows: auto;
grid-template-columns: repeat(4, 1fr);
grid-row-gap: 1em;
grid-column-gap: 1em;
<div class="wrapper">
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
</div>
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
</div>
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
</div>
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
</div>
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
</div>
</div>
使用 *ngFor... 它运行数组“stickyNotes”的长度,但仅在每行下方堆叠框。
<div class="wrapper" *ngFor="let s of stickyNotes; let i = index" >
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
<p>s.title</p>
</div>
</div>
我对此的破解是...在 *ngIf(i+1、i+2 等)上将这个 div 元素添加 4 次,其中 i 增加 1。这里的问题是,当新行开始时,CSS 中的 grid-row-gap 会被忽略。
<div class="item2" style="background-color: deepskyblue;" *ngIf="i < stickyNotes.length && i%4 === 0">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
<p>stickyNotes[i].title</p>
</div>
<div class="item2" style="background-color: deepskyblue;" *ngIf="i+1 < stickyNotes.length && i%4 === 0">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
<p>stickyNotes[i+1].title</p>
</div>
<!--2 more times until i+3-->
我想知道是否有一种方法可以创建自定义可迭代指令,而不会破坏网格属性,也无需将 item2 类编码 4 次(或任何其他方法)。
我尝试过引导行和列属性,但是有 4 列,响应性不如网格布局。
任何帮助或建议将不胜感激!
【问题讨论】:
【参考方案1】:*ngFor 重复你添加它的元素。只需将它放在div.item2
上,它应该可以工作:
<div class="wrapper" >
<div class="item2" *ngFor="let s of stickyNotes; let i = index" style="background-color: deepskyblue;" >
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
<p>s.title</p>
</div>
</div>
Vega 提供的答案也可以,但<ng-container>
不是必需的(只要您不在div.item2
元素上添加另一个structural directive),因为星号只是语法糖并扩展为something similar:
<div class="wrapper" >
<ng-template ngFor let-s [ngForOf]="stickyNotes" let-i="index">
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
<p>s.title</p>
</div>
</ng-template>
</div>
每个元素一个结构指令的限制背后的原因是given here:
有一天,您会想要重复一段 html,但前提是特定条件为真。您将尝试将 *ngFor 和 *ngIf 放在同一个宿主元素上。 Angular不会让你。您只能将一个结构指令应用于一个元素。
原因是简单。结构指令可以对宿主元素及其后代做复杂的事情。当两个指令声明同一个宿主元素时,哪一个优先? NgIf 或 NgFor 应该先走哪一个? NgIf 可以取消 NgFor 的效果吗?如果是这样(看起来应该是这样),Angular 应该如何概括取消其他结构指令的能力?
这些问题没有简单的答案。禁止多个结构性指令使它们没有实际意义。这个用例有一个简单的解决方案:将 *ngIf 放在包装 *ngFor 元素的容器元素上。一个或两个元素都可以是 ng 容器,因此您不必引入额外的 HTML 级别。
【讨论】:
效果很好。太感谢了!!无法在 div 元素上放置结构指令的原因是什么? 我想说的是,你不能将两个结构指令放在一个元素上。我会编辑我的答案【参考方案2】:试试这个语法:
<div class="wrapper">
<ng-container *ngFor="let s of stickyNotes; let i = index">
<div class="item2" style="background-color: deepskyblue;">
<img class="img-responsive img-rounded" src="assets/Logo/square_filler.png" >
<p>more text here.</p>
<p>s.title</p>
</div>
</ng-container>
</div>
【讨论】:
这个也可以!没想到这么简单...谢谢!以上是关于在 CSS 网格布局中使用 *ngFor 不希望地在一列中显示所有内容的主要内容,如果未能解决你的问题,请参考以下文章