在CSS网格布局中使用* ngFor无意中显示一列中的所有内容

时间:2017-09-12 16:58:16

标签: html css angular typescript css-grid

我是编程和Web开发人员的新手。我正在建立一个个人网站。

我想将框放在一个包含4列的网格中,类似于您在此处看到的内容:https://devpost.com/software/search?query=is%3Afeatured

这些方框中的每一个都代表一个对象,我希望能够在框中显示一些数据,并在单击该框时在弹出对话框中显示其余数据。

我必须使用CSS网格布局,这种情况近来越来越受欢迎(强烈推荐此视频:https://www.youtube.com/watch?v=7kVeCqQCxlk)。

当我在包装器div中硬编码div元素时,有4列的东西工作。但是,每当我在包含我的数据数组的包装器上使用* ngFor并将每次迭代的数据输入到内部div元素时,网格布局就会被破坏,将所有内容放在一列中。

当我使用多个div元素(此处为第2项)手动输入数据时,它可以根据需要运行:



.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" alt="pic-test" >
        <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" alt="pic-test" >
        <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" alt="pic-test" >
        <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" alt="pic-test" >
        <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" alt="pic-test" >
        <p>more text here.</p>
    </div>
    
</div>
&#13;
&#13;
&#13;

使用* ngFor ...它运行数组的长度&#34; stickyNotes,&#34;但只在每行下方堆叠框。

&#13;
&#13;
<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" alt="pic-test" >
        <p>more text here.</p>
        <p>{{s.title}}</p>
    </div>
</div>
&#13;
&#13;
&#13;

我的黑客围绕这个...有这个div元素4次,我在* ngIf(i + 1,i + 2等)上递增1。这里的问题是当一个新行开始时,CSS中的grid-row-gap被忽略。

&#13;
&#13;
<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" alt="pic-test" >
      <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" alt="pic-test" >
      <p>more text here.</p>
      <p>{{stickyNotes[i+1].title}}</p>
</div>

<!--2 more times until i+3-->
&#13;
&#13;
&#13;

我想知道是否有办法创建自定义可迭代指令而不破坏网格属性并且没有将item2类编码4次(或任何其他方法)。

我尝试过bootstrap row和col属性,但是有4列,响应性并不像网格布局那么好。

任何帮助或建议都将不胜感激!

2 个答案:

答案 0 :(得分:4)

* 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" alt="pic-test" >
        <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" alt="pic-test" >
      <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-container,因此您不必引入额外的HTML级别。

答案 1 :(得分:1)

试试这个语法:

<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" alt="pic-test">
      <p>more text here.</p>
      <p>{{s.title}}</p>
    </div>
  </ng-container>
</div>