来扯点ionic3[4] 结构型指令和列表渲染

96
忠叔
2017.11.11 20:06* 字数 1206

往期传送门
来扯点ionic3[0] 吹完牛再入门也不迟
来扯点ionic3[1] 创建一个新页面
来扯点ionic3[2] 页面一线牵 珍惜这段缘
来扯点ionic3[3] 页面的生命周期事件,也就是凡间所说的钩子

《雷神3》上映已经一周,但因为各种原因还没来得去送票房,有多年不见的班纳和洛基娘娘,期待他们在《诸神黄昏》和明年《无限战争》中的表现。

之前在学习建立页面的时候已经体验过了模板插值(把变量展示在页面中),这一节便来挖掘更多的模板语法。

准备工作

方便起见,我们这次处理项目中的默认页面 ContactPage,在 contact.ts 中建立一个简单的数组成员。


contact.ts

在 contact.html 中清空 ion-content 标签的多余内容。


contact.html

至此,准备就绪,开始了解第一个指令。

重复性指令 ngFor

ngFor指令的作用是,将批量的数据(数组)结合HTML元素添加到页面DOM中,它的语法参照了ES6中的 for...of 语句:

for (let i of [1,2,3,4,5,6]) { ... }

基本的使用

ngFor指令基本语法:

*ngFor="let value of [1,2,3,4,5,6]"

使用时注意不要遗漏星号(*)。

尝试在 contact.html 中输出 data 数组:

<ion-content>
  <div *ngFor="let item of data">{{item}}</div>
</ion-content>

模板中渲染的数据和页面类中的属性成员是紧密绑定的,当属性发生变化,页面也会当即作出相应:

ionViewDidEnter(){
    setInterval(()=>{
        this.data.push(this.data.length + 1);
    },500)
  }

在上面的代码中,使用钩子添加了一个间隔定时器,每半秒钟向 data 数组中添加一个元素(在ionic3中,如果没有特殊的必要,请使用箭头函数代替传统的
function 声明
)。

动图:动态渲染效果

可见,在页面中,每半秒钟也会相应增加一个新的条目。

对象的渲染

在实际的开发中,我们更常会去处理一个对象数组,这时候我们通过点运算符(.) 输出数组的属性:

    data:any = [
        {name:'托尼·史塔克', birthYear:1970, gender:1, description:'钢铁侠'},
        {name:'史蒂夫·罗杰斯', birthYear:1920, gender:1, description:'美国队长'},
        {name:'娜塔莎罗·曼诺夫', birthYear:1928, gender:0, description:'黑寡妇'},
        {name:'索尔', birthYear:-5555,gender:1, description:'雷神'},
        {name:'克林顿·巴顿', birthYear:1974, gender:1, description:'鹰眼'},
        {name:'布鲁斯·班纳', birthYear:1975, gender:1, description:'绿巨人浩克'}
    ]; 

模板渲染:

<ion-content>
  <div *ngFor="let item of data">{{item.name}}</div>
</ion-content>
渲染效果

ionic的列表渲染

基本使用

在APP的开发中,对列表条目的渲染并非是通过 div 来承载的,ionic 提供了列表专用的标签 ion-list

<ion-list>
  <ion-item></ion-item>
</ion-list>

其中 ion-list 是列表容器, ion-item 是列表中的一个条目,当把 ion-item 和 ngFor 指令结合使用,就可以渲染出一个多条目的列表:

<ion-content>
  <ion-list>
    <ion-item *ngFor="let item of data">{{item.name}}</ion-item>
  </ion-list>
</ion-content>

更复杂一些的列表

ion-item 里可以通过不同元素的组织让列表承载更多信息


<ion-item *ngFor="let item of data">
  <h2>{{item.name}}</h2>
  <p>{{item.description}}</p>
</ion-item>
image.png

此外,ionic还提供一个指令 item-end 将指定的元素渲染在条目的尾部:

<ion-item *ngFor="let item of data">
      <h2>{{item.name}}</h2>
      <p>{{item.description}}</p>
      <p item-end>{{item.gender?'男':'女'}}, {{2017 - item.birthYear}} 岁</p>
    </ion-item>

注:漫威电影宇宙中超级英雄的出生年份不可考 :)

此处除了点运算符(.) 输出对象的属性,还使用了一个计算表达式和一个条件表达式,这些都是我们常见的用法。

加入头像

利用 ion-avatar 标签和 item-start 指令渲染一个有头像的列表:


ion-avatar标签的默认样式会自动对图片进行缩放和截取,呈现出如图所示的圆形效果,此外也有一种可以展示方形图片的 ion-thumbnail 标签(缩略图标签),你也可以通过CSS来修改头像的样式。
注:我事先已经准备好了图片素材并将每位hero的avatar属性写进了data中。

有条件地渲染:ngIf 指令

除了 ngFor ,还有一个非常常用的指令 ngIf ,通过一个表达式来判断元素是否会被添加到模板中。这一指令同样也是动态的:当表达式的值变为真,元素便会添加;当表达式的值变为假,元素会从模版中被移除。

*ngIf="isActive"

尝试用 ngIf 指令来晒先男性英雄

<ion-list>
    <ng-container *ngFor="let item of data">
      <ion-item *ngIf="item.gender===1">
        <ion-avatar  item-start>
          <img src="{{item.avatar}}">
        </ion-avatar>
        <h2>{{item.name}}</h2>
        <p>{{item.description}}</p>
        <p item-end>{{item.gender?'男':'女'}}, {{2017 - item.birthYear}} 岁</p>
      </ion-item>
    </ng-container>
  </ion-list>

这儿要说明的是,在angular中,*ngFor 和 *ngIf 不能放置在同一个标签上(Vue之类的框架则可以),因此在 ion-item 外加上一个“虚拟”的标签 ng-container, 它自身不会被渲染到DOM中,只会渲染它包裹的内容(类似Vue中的 template 标签)。因此在没有 ngIf 的情况下,把 ngFor 指令加在 ion-item 上和加在外层的 ng-container 标签上效果是等同的;而在有 ngIf 指令的情况下,可以通过 ng-container标签避免两个指令的冲突

参考文档

  1. Angular结构型指令
  2. Ionic List API Docs
  3. Ionic Item API Docs

下一章:来扯点ionic3[5] 轻松上手表单:这些组件可以玩一年

来扯点ionic