Anglar *ngFor 指令的使用 详细版

        在工作时,遇到了后端的返回的response是一个如下结构的数据的对象(对象中的属性值是对象属性),需要把下面对象中的currentYears、previousYears两个的数据都在html中分别进行显示。

year = 
    {
        currentYears:[{month:'',day:''},{month:'',day:''}],
        previousYears:{2016:[{month:'',day:''},{month:'',day:''}],2017:[{month:'',day:''},{month:'',day:''}]}
    }

当时采用的方法是:*ngFor 循环

        一般来说,*ngFor使用来循环数组的,循环对象会有报错:Cannot find a differ supporting object 'object' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

        这个时候最直接的就是使用keyValue这个管道https://angular.io/api/common/KeyValuePipe(本文后面会写到将对象转化成数组从而再循环处理)

<ng-container *ngIf="currentYears.length>0; then currentYears; else previousYears"></ng-container>

//html 
 <div #currentYears>
    <div *ngFor="let current of currentYears">
      {{current.month}}-{{current.year}}
    </div>
  </div>
  <div #previousYears>
    <div *ngFor="let preivous of previousYears | keyValue">
      <span>{{preivous.key}}</span>//2016, 2017
      <div *ngFor="let item of preivous.value | keyValue:unsorted">
        <span>{{item.month}}-{{item.day}}</span>
      </div>
    </div>
  </div>

  <script>
    //这里展示的是不排序的显示,当然如果有排序的要求,可以根据实际情况进行编写排序的程序代码
    unsorted(a: any, b: any):Number {
      return 0;
    }
    //比如降序的
    desendingOrder(a: KeyValue < string, any >, b: KeyValue < string, any >) {
      const s = a.key;
      const t = b.key;
      return t > s ? 1 : (s > t ? -1 : 0);
    }
  </script>

//当previousYear这个对象有数据,输出效果如下:
2016:month-day
2017: month-day

        在上述代码中,我们使用了 *ngFor 指令来循环遍历 previousYears 对象。*ngFor="let year of previousYears | keyvalue" 表示我们要遍历 previousYears 对象,并将键(年份)和值(日期数组)存储在 year 变量中。然后使用 *ngFor="let item of year.value",在每个年份内部循环遍历日期数组。在模板中使用插值绑定 {{ }} 来显示具体的月份和日期。

        其实在发现上面的这个处理方法的时候,最初使用的处理方法是使用自定义指令

```html
<div appYearRenderer [years]="previousYears"></div>
```

```typescript
import { Directive, Input, ElementRef } from '@angular/core';

@Directive({
  selector: '[appYearRenderer]'
})
export class YearRendererDirective {
  @Input('appYearRenderer') years: any;

  constructor(private el: ElementRef) { }

  ngOnInit() {
    for (let year in this.years) {
      const yearDiv = document.createElement('div');
      yearDiv.innerHTML = `<h2>${year}</h2>`;
      const ul = document.createElement('ul');
      this.years[year].forEach(obj => {
        const li = document.createElement('li');
        li.innerText = `${obj.month} - ${obj.day}`;
        ul.appendChild(li);
      });
      yearDiv.appendChild(ul);
      this.el.nativeElement.appendChild(yearDiv);
    }
  }
}
```

        在上面的示例中,我们创建了一个名为 `appYearRenderer` 的指令,它接受一个名为 `years` 的输入属性,在组件中传入 `previousYears` 对象。在指令的 `ngOnInit` 生命周期钩子中,我们使用原生 JavaScript 创建 HTML 元素并将其附加到指令所在的元素中,实现了数据的渲染和展示。

        后面经过在冲浪时又想起了这个问题,发现了另外的处理方法,就是使用Obejct.key()将对象进行转化

<ng-container *ngIf="currentYears.length>0; then currentYears; else previousYears"></ng-container>

  <div #currentYears>
    <div *ngFor="let current of currentYears">
      {{current.month}}-{{current.year}}
    </div>
  </div>
  <div #previousYears>
    <div *ngFor="let preivous of Object.key(previousYears)">
      <span>{{preivous}}</span>//2016, 2017
      <div *ngFor="let item of previousYears[preivous]">
        <span>{{item.month}}-{{item.day}}</span>
      </div>
    </div>
  </div>

        总而言之,以上三种方法能达到一样的效果,具体使用哪种方法,就看各位的喜好了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值