這篇要動手囉!
先去 github 拉一下基底
git clone -b start https://github.com/angular-in-action/datacenter.git
接著來建立一個資料 Component
先建立一個 DashboardComponent
ng g c dashboard
controller 的內容如下:
import { Component, OnInit, OnDestroy } from '@angular/core';
interface Metric {
used: number,
available: number
};
interface Node {
name: string,
cpu: Metric,
mem: Metric
};
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit, OnDestroy {
cpu: Metric;
mem: Metric;
cluster1: Node[];
cluster2: Node[];
interval: any;
constructor() {}
ngOnInit(): void {
this.generateData();
this.interval = setInterval(() => {
this.generateData();
}, 15000);
}
ngOnDestroy(): void {
clearInterval(this.interval);
}
generateData(): void {
this.cluster1 = [];
this.cluster2 = [];
this.cpu = { used: 0, available: 0 };
this.mem = { used: 0, available: 0 };
for (let i = 1; i < 4; i++) this.cluster1.push(this.randomNode(i));
for (let i = 4; i < 7; i++) this.cluster2.push(this.randomNode(i));
}
private randomNode(i): Node {
let node = {
name: 'node' + i,
cpu: { available: 16, used: this.randomInteger(0, 16) },
mem: { available: 48, used: this.randomInteger(0, 48) }
};
this.cpu.used += node.cpu.used;
this.cpu.available += node.cpu.available;
this.mem.used += node.mem.used;
this.mem.available += node.mem.available;
return node;
}
private randomInteger(min: number = 0, max: number = 100): number {
return Math.floor(Math.random() * max) + 1;
}
}
再來我們修改 template dashbaord.component.html 如下:
<p>{{cluster1 | json}}</p>
最後一步就是把我們定義好的 Component 放到 AppComponent 的 template 上, 這樣才能看到畫面長怎樣囉~
<app-navbar></app-navbar>
<app-dashboard></app-dashboard>
我們開發完了資料 Component,接著就是要決定如何呈現資料 Component 所持有的資料
首先,我們再建立一個 MetricComponent
ng g c metric
然後一如往常,先在 controller 填入以下內容:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-metric',
templateUrl: './metric.component.html',
styleUrls: ['./metric.component.css']
})
export class MetricComponent {
@Input() title: string = '';
@Input() description: string = '';
@Input('used') value: number = 0;
@Input('available') max: number = 100;
isDanger() {
return this.value / this.max > 0.7;
}
}
接著定義的是 Template 的部份,我們會在這用到 Angular Bootstrap 的 UI 元件連示範如何使用從 @Input 收到的值
<div class="card card-block">
<div class="card-body">
<nav
class="navbar navbar-dark bg-primary mb-1"
[ngClass]="{ 'bg-danger': isDanger(), 'bg-success': !isDanger() }"
>
<h1 class="navbar-brand mb-0">{{ title }}</h1>
</nav>
<h4 class="card-title">
{{ value }}/{{ max }} ({{ value / max | percent: "1.0-2" }})
</h4>
<p class="card-text">
{{ description }}
</p>
<ngb-progressbar
[value]="value"
[max]="max"
[type]="isDanger() ? 'danger' : 'success'"
></ngb-progressbar>
</div>
</div>
定義完 MetricComponent 的 controller 與 template,是時候使用它了
<div class="container mt-2">
<div class="card card-block">
<nav class="navbar navbar-dark bg-inverse mb-1">
<h1 class="navbar-brand mb-0">Overall Metrics</h1>
</nav>
<div class="row">
<app-metric
class="col-sm-6"
[used]="cpu.used"
[available]="cpu.available"
[title]="'CPU'"
[description]="'utilization of CPU cores'"
>
</app-metric>
<app-metric
class="col-sm-6"
[used]="mem.used"
[available]="mem.available"
[title]="'Memory'"
[description]="'utilization of memory in GB'"
>
</app-metric>
</div>
</div>
</div>
Dashboard 目前為止建一半了,小結一下: