在实际工作中,我们常常会需要某一块的网页内容重复出现,像是动态的抓资料然後塞到 table 的 row 里面。笔者第一份工作刚接触前端时,连 jQuery 都不太会用,那时候凭着一股傻劲,抓完资料直接用回圈组字串塞到 table 的 innerHtml,回想起来真是好傻好天真。现在我们有了 Angular 当然不用再这样傻傻地自干,我们今天就来介绍三个基础的 Structural Directive(结构型指令)
ngFor 指令可以从一个阵列中读出每一个元素,然後根据这些元素的内容长出 HTML 内容。上面提到的抓资料动态塞到 table row 就非常适合用 ngFor 来处理,因为一个 table 里的资料格式基本上都是固定的,只要跑回圈就能一个萝卜一个坑,一行一行的把 row 加到 table 里就能把所有资料显示出来。
上次我们用 IronmanComponent 来显示单一使用者的资讯,今天我们来新增一个 component,用 table 显示一个使用者清单。
在我们加入越来越多自己的东西之後,Angular 自动产生的 HTML 内容会显得很碍眼,现在可以视个人喜好决定要不要把 删掉。笔者是留下上面的 ToolBar,然後
<div class="content" role="main">
里除了<router-outlet></router-outlet>
全砍了
首先一样用指令或者 Extension 的功能新增一个 component,这里笔者就叫他 ironman-list。
@Input()
userList: IronmanUser[] = [];
userListFromAppComponent: IronmanUser[] = [
{
userId: 1,
userName: 'Alice',
email: '[email protected]',
verified: 1
},
// ...
// 其他资料
// ...
]
<app-ironman></app-ironman>
删掉或注解 <!-- <app-ironman
[(userInfo)]=userInfoFromAppComponent
(testOuputEvent)=handleTestEvent($event)>
</app-ironman> -->
<app-ironman-list [userList]=userListFromAppComponent></app-ironman-list>
<tbody>
<tr *ngFor="let user of userList">
<td>{{user.userId}}</td>
<td>{{user.userName}}</td>
<td>{{user.email}}</td>
<td>{{user.verified}}</td>
</tr>
</tbody>
执行程序,应该就能看到我们只写了一份 <tr>…</tr>
就长出所有的内容了!这里我们来稍微解释一下 ngFor 的语法:
网页应用中,我们也常常会需要根据资料的某个栏位,来决定要不要显示某个内容,而这种需求,我们可以很容易地利用 *ngIf 来达到。这里我们就来就绍一下 *ngIf 的用法。
假设我们今天的需求是:如果某个使用者已经通过认证,那管理员就能点编辑按钮编辑这个使用者的资料,那我们只要对刚刚的 table 稍作修改,加入一行 *ngIf 的语法,就能达到这样的效果
<tbody>
<tr *ngFor="let user of userList">
<td>{{user.userId}}</td>
<td>{{user.userName}}</td>
<td>{{user.email}}</td>
<td>{{user.verified}}</td>
<td>
<button *ngIf="user.verified === 1">编辑</button>
</td>
</tr>
</tbody>
上面的程序中,*ngIf 的宿主是 button 元素,而且这个 button 只有在 user.verified 这个属性等於 1 的时候才会被渲染出来。
有些时候,我们可能不只需要用二分法来决定页面的显示,可能需要根据不同的值来显示不同的内容,ngIf 虽然能做到,但是程序码看起来总会觉得有点脏,这时候,ngSwitch 就派上用场了!
首先,先在 app.component.ts 的资料来源中加一笔 verified 有异常值的假资料,不然我们目前只有 0 跟 1 XD
userListFromAppComponent: IronmanUser[] = [
// 前面不变
{
userId: 999,
userName: 'Bug',
email: '',
verified: -1
},
接着,稍微修改一下 ironman-list.component.html 的内容,把原本单纯输出 verified 的地方改成 ngSwitch
<tbody>
<tr *ngFor="let user of userList">
<td>{{user.userId}}</td>
<td>{{user.userName}}</td>
<td>{{user.email}}</td>
<td [ngSwitch]="user.verified">
<p *ngSwitchCase="1">已认证</p>
<a *ngSwitchCase="0" href="#">前往认证</a>
<p *ngSwitchDefault class="text-danger;">BUG</p>
</td>
<td>
<button *ngIf="user.verified === 1">编辑</button>
</td>
</tr>
ngSwitch 一样需要一个宿主,然後在这个宿主里面,只有条件成立的 case 会被渲染出来。执行程序就会看到我们的 table 根据不同的 verified 属性值显示不同的元素,这里稍微注意一下 ngSwitch 的语法有点不同,switch 的地方是用中括号的属性系结,case 的地方才是用 directive(星号)。
有些时候,如果我们所使用的 CSS 在选取上很难改,擅自增加一个宿主元素可能会让 CSS 跑掉,这个时候我们可以多写一个 <ng-container></ng-container>
来当宿主,ng-container 在被编译成 JS 之後会变成注解,所以就不会影响到 CSS 的目标选取。例如,上面的 ngIf 也可以改成
<td>
<ng-container [ngSwitch]="user.verified">
<p *ngSwitchCase="1">已认证</p>
<a *ngSwitchCase="0" href="#">前往认证</a>
<p *ngSwitchDefault class="text-danger">BUG</p>
</ng-container>
</td>
以上就是最基本、常用的三个结构型指令(structural directive),用这三个结构型指令就能让我们很灵活的决定网页的内容。明天,我们会介绍一下基本的 Angular 的 HttpClient,这样我们就真的不用把资料写死了。
>>: 110/12 - 把照片储存在Pictures/应用程序名称资料夹 - 2
学习新知的第一步是初步了解原理,学习新的开发技术除了原理也要先学习设定环境。 写在最最最前面 虽然N...
好一阵子没写单元测试与整合测试了,大家是否觉得有些生疏了呢? 之前的测试都写得很简单,正好昨天好好...
解释以下SQL语句: INSERT INTO departments(department_id, ...
各位可以把频道(Channel)想像是服务提供者(Provider)所建立的LINE帐号,藉此和使用...
第 12 天要来介绍 interface 那麽话不多说,我们就进入正题吧 ─=≡Σ(((っ゚∀゚)っ...