如何在Angular 2中有条件地关闭HTML标签

4

在php中,有可能以条件方式关闭html标签。我们能否在Angular 2中模拟类似的功能呢?

例如:

<p>
    Some lorem
<?php  if(someConditionTrue){ echo "</p>"}; ?>

HTML标签应该被关闭。您能否解释一下为什么您不想关闭它? - Ploppy
当某个条件成立时,我想在 ngFor 的某个点关闭它,类似于我提供的示例。感谢您纠正我的帖子,Pierre! - Marko Djordjevic
那么你应该将段落的内容放入一个变量中,并将该变量绑定到“p”标签。 - Ploppy
所以我有一个简单的数组,其中包含一些数据,我的期望输出是<div class="row"> <div>item1</div> <div>item2</div> <div>item3</div> <div>item4</div> </div> <div class="row"> <div>item5</div> <div>item6</div> <div>item7</div> <div>item8</div> </div> 在数组中的每四个项目上,我想打开行显示四个项目并关闭它。我已经通过将数组转换为多维数组,然后使用嵌套的ngFor指令来完成了这个操作,但我想知道是否可能类似于php。 - Marko Djordjevic
1
Angular2 不支持这个。 - Günter Zöchbauer
5个回答

3
虽然它能起作用,但可能存在更好的解决方案,请参见下面的说明。
该组件的脚本:
private items: string[] = ['test1','test2','test3','test4','test5','test6','test7','test8','test9'];

HTML:

<div *ngFor="let item of items; let i = index">
    <div class="row" *ngIf="i%4==0">
        <div *ngIf="items[i]">{{items[i]}}</div>
        <div *ngIf="items[i+1]">{{items[i+1]}}</div>
        <div *ngIf="items[i+2]">{{items[i+2]}}</div>
        <div *ngIf="items[i+3]">{{items[i+3]}}</div>
    </div>
</div>

https://plnkr.co/edit/RDZFJFEZtTD0NA5d8YNJ?p=preview

注意:最好创建一个数组(行),其中包含数组(项),而不是使用我发布的“仅模板”解决方案。

该链接是关于IT技术的内容,它展示了一个网页模板。建议使用数组来存储数据,以便更好地组织和管理信息。


1
当我尝试以响应式的方式展示三列数据时,遇到了问题。我需要在三个列中显示具有不同高度的方块数据(实际上它们是mat-expansion-panel)。我首先尝试使用Angular的flex布局,但由于方块之间有空白(在底部和顶部),这并不理想。最终,我通过使用Angular的Bootstrap发现了一个有效的布局。我需要动态显示一定数量的方块,分为三列显示。最终效果应该类似于这样(9个方块的示例)。
<div class="container-fluid">
    <div class="row justify-content-start">
        <div class="col-12 col-lg-4">
            <box1></box1>
            <box1></box1>
            <box1></box1>
        </div>
        <div class="col-12 col-lg-4">
            <box1></box1>
            <box1></box1>
            <box1></box1>
        </div>
        <div class="col-12 col-lg-4">
            <box1></box1>
            <box1></box1>
            <box1></box1>
        </div>
    </div>
</div>

我的第一个想法是在
上放置ngFor,以循环遍历所有的盒子,但问题是……如何让
每3个盒子出现一次? 我从这篇帖子中得到了一些帮助,在谷歌上寻找解决方案整整一天,但我没有找到任何解决方案。 最终,我想出了以下解决方案,并且适用于任何数量的盒子。
<div class="container-fluid">
    <div class="row justify-content-start">
        <div class="col-12 col-lg-4">
            <ng-container *ngFor="let cat of categoryProducts; let i = index">
                <box1 *ngIf="i%4 == 0">{{cat.name}}</box1>
            <ng-container
        </div>
        <div class="col-12 col-lg-4">
            <ng-container *ngFor="let cat of categoryProducts; let i = index">
                <box1 *ngIf="i%4 == 1">{{cat.name}}</box1>
            <ng-container
        </div>
        <div class="col-12 col-lg-4">
            <ng-container *ngFor="let cat of categoryProducts; let i = index">
                <box1 *ngIf="i%4 == 2">{{cat.name}}</box1>
            <ng-container
        </div>
    </div>
</div>

这个解释是这样的。例如:假设我们有一个类别产品数组。它们将具有以下索引[0、1、2、3、4、5、6、7、8]。 正如您所看到的,解决方案将在同一个数组上循环3次(有点冗余,但没关系)。 在第一个循环中,我们只考虑这些索引的元素:0、3、6。其他元素将被忽略,但将在下面的两个循环中考虑。 在第二个循环中,我们只考虑这些索引的元素:1、4、7。其他元素将被忽略。 在第三个循环中,我们只考虑这些索引的元素:2、5、8。其他元素将被忽略,但已在其他循环中显示。 box1可以是您需要的任何元素:div、mat-expansion-panel、组件等。 该示例有3列,但您可以用它来处理任意数量的列。在我的情况下,我需要4个。 对于任何数量的框,这都可以很好地工作。所有这些框都将分成3列。

1
这是PHP开发者常见的困惑,不是对Angular或其他框架(如Ionic)的拒绝。不幸的是,您不能在闭合HTML标签上放置*ngIf条件,当您将条件放在开头的
上时,您将有条件地排除
中的所有内容--而不仅仅是您要定位的标签。

因此,最终您的代码会相当冗余,但您可以通过以下方式解决问题:

<div class="iterable-container">
 <div *ngFor="let item of items; let i = index">
  <div class="iterable-col-1" *ngIf="(i+3) % 3 == 0">
   <p>first column: {{item.name}}</p>
  </div>
  <div class="iterable-col-2" *ngIf="(i+3) % 3 == 1">
   <p>second column: {{item.name}}</p>  
  </div>
  <div class="iterable-col-3" *ngIf="(i+3) % 3 == 2">
   <p>third column: {{item.name}}</p>
  </div>
 </div>
</div>

您还需要一些CSS。以下是一些起始样式:

.iterable-container {
  background-color: #f2f2f2;
}

.iterable-col-1 {
  display: flex;
  height: 175px;
}

.iterable-col-2 {
  display: flex;
  height: 0;
  left: 33%;
  position: relative;
  top: -175px;
}

.iterable-col-3 {
  display: flex;
  height: 0;
  left: 66%;
  position: relative;
  top: -175px;
}

考虑放弃使用那些
标签,转而使用老式的HTML标签也许是值得的。虽然她可能已经过时了,但我觉得她几乎是为此而建立的。

我的上一个例子假设您需要每个列(由“第一”,“第二”,“第三”表示,但可以是任何内容)的不同内容。 - Ben Hulan

0

你为什么需要这个?这似乎是在与框架对抗而不是拥抱它。

有几种类似的方法,比如ng-if、ng-repeat和ng-show。

一种方法是:

<p>
   <span ng-show='condition' ng-repeat='item in collection'>
       {{item.Text}}
   </span>
</p>

0

我的先前的回答假设你需要每列(由文本“first”、“second”、“third”表示)不同的内容。

Simon Aronsson 正确指出了这是违反框架的。如果你只需要一致风格的行和列内容,可以简化如下:

<div class="iterable-container">
   <div *ngFor="let item of items">
     <div class="iterable-col of-3">
       <p>{{item.name}}</p>
     </div>
  </div>
</div>

我使用.of-2.of-3类来将相似的架构应用于2列和3列视图。以下是一些起始Sass代码:

// assumes you have a color map:
.iterable-container { 
  background-color: color($colors, light); 
}
.iterable-col {
  display: flex;
  position: relative;
  float: left;
  clear: right;
}
// first column
.iterable-col {
  &.of-2:nth-of-type(2n+1){
    width: 50%;
    max-height: 300px; // depending on size of your card
  }
  &.of-3:nth-of-type(3n+1){
    width: 33.33%;
  }
}
// 2nd of 3 columns
.iterable-col.of-3:nth-of-type(3n+2){
  width: 33.33%;
}
// last column
.iterable-col{
  &.of-2:nth-of-type(2n){
    width: 50%;
    max-height: 300px;
  }
  &.of-3:nth-of-type(3n){
    width: 33.33%;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接