这就是这个示例教程的最终效果。
上面一个导航条,然后是2个页面。
创建项目
> ng new myapp
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS
创建完成后,运行:
> cd myapp
> ng serve -o
创建导航
打开 /src/app/app.component.html
,删除内容,添加:
<header>
<div class="container">
<a routerLink="/" class="logo">CoolApp</a>
<nav>
<ul>
<li><a href="#" routerLink="/">Home</a></li>
<li><a href="#" routerLink="/list">List</a></li>
</ul>
</nav>
</div>
</header>
<div class="container">
<router-outlet></router-outlet>
</div>
- routerLink - 类似于 href,在 angular 中要使用 routerLink,而不是 href
- router-outlet - 目标组件显示的位置
打开 /app/styles.scss
,添加:
@import url('https://fonts.googleapis.com/css?family=Nunito:400,700&display=swap');
$primary: rgb(111, 0, 255);
body {
margin: 0;
font-family: 'Nunito', 'sans-serif';
font-size: 18px;
}
.container {
width: 80%;
margin: 0 auto;
}
header {
background: $primary;
padding: 1em 0;
a {
color: white;
text-decoration: none;
}
a.logo {
font-weight: bold;
}
nav {
float: right;
ul {
list-style-type: none;
margin: 0;
display: flex;
li a {
padding: 1em;
&:hover {
background: darken($primary, 10%);
}
}
}
}
}
h1 {
margin-top: 2em;
}
路由
创建2个组件:
> ng generate component home
> ng generate component list
打开 /src/app/app-routing.module.ts
添加:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component'; // Add this
import { ListComponent } from './list/list.component'; // Add this
const routes: Routes = [
{ path: '', component: HomeComponent }, // Add this
{ path: 'list', component: ListComponent } // Add this
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
单向数据绑定
打开 /src/app/home/home.component.html
,替换内容为:
<h1>Welcome!</h1>
<div class="play-container">
<p>You've clicked <span (click)="countClick()">this</span> {{ clickCounter }} times.</p>
</div>
- (click) - 这是一个点击事件,如果元素被点击,就会调用函数 countClick()
- {{ clickCounter }} - 显示组件属性 clickCounter 的值
home.component.ts
中添加:
export class HomeComponent implements OnInit {
clickCounter: number = 0;
constructor() { }
ngOnInit() {
}
countClick() {
this.clickCounter += 1;
}
}
home.component.scss
中添加:
span {
font-weight: bold;
background: lightgray;
padding: .3em .8em;
cursor: pointer;
}
.play-container {
padding: 3em;
border: 1px solid lightgray;
margin-bottom: 1em;
input {
padding: 1em;
margin-bottom: 2em;
}
}
双向数据绑定
home.component.html
中添加:
<div class="play-container">
<p>
<input type="text" [(ngModel)]="name"><br>
<strong>You said: </strong> {{ name }}
</p>
</div>
/src/app/app.module.ts
中添加:
// other imports
import { FormsModule } from '@angular/forms';
@NgModule({
...
imports: [
BrowserModule,
AppRoutingModule,
FormsModule // add this
],
providers: [],
bootstrap: [AppComponent]
})
home.component.ts
中定义 name
属性:
clickCounter: number = 0;
name: string = ''; // add this
ng-template
home.component.html
中添加:
<div class="play-container">
<ng-template [ngIf]="clickCounter > 4" [ngIfElse]="none">
<p>The click counter <strong>IS GREATER</strong> than 4.</p>
</ng-template>
<ng-template #none>
<p>The click counter is <strong>not greater</strong> than 4.</p>
</ng-template>
</div>
[ngIf]
绑定一个表达式*clickCounter > 4*
。
如果表达式为 false
,将会调用ngIfElse
指定的名为none
的模板。
如果表达式为 true
,将会显示ng-template
块中的HTML内容。
样式绑定
打开home.component.html
,修改最后一个 play-container
class :
<div class="play-container" [style.background-color]="clickCounter > 4 ? 'yellow' : 'lightgray'">
clickCounter > 4
之后,背景色就会变为黄色。
还可以指定多个CSS属性:
<div class="play-container" [ngStyle]="{
'background-color': clickCounter > 4 ? 'yellow' : 'lightgray',
'border': clickCounter > 4 ? '4px solid black' : 'none'}
">
Class 绑定
如果你想添加或者移除定义在CSS中的class,可以使用class绑定。
修改当前 play-container
:
<div class="play-container" [class.active]="clickCounter > 4">
home.component.scss
中添加:
.active {
background-color: yellow;
border: 4px solid black;
}
可以使用 ngClass
设置多个 class:
<div class="play-container" [ngClass]="setClasses()">
home.component.ts
中添加:
setClasses() {
let myClasses = {
active: this.clickCounter > 4,
notactive: this.clickCounter <= 4
};
return myClasses;
}
home.component.scss
中添加:
.notactive {
background-color: lightgray;
}
Service
Service 可以复用,接下来我们创建一个 service,用来调用 api 获取数据,并显示在 list 页面。
ng g s http
g s
是 generate service
的缩写。
我们给这个service命名为http
。
/src/app/http.service.ts
中添加一个自定义的方法:
export class HttpService {
constructor() { }
myMethod() {
return console.log('Hey, what is up!');
}
}
/src/list/list.component.ts
中添加调用 myMethod
:
export class ListComponent implements OnInit {
constructor(private _http: HttpService) { }
ngOnInit() {
this._http.myMethod();
}
}
ngOnInit()
会在组件加载时触发。
Angular HTTP Client
http.service.ts
中添加:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class HttpService {
constructor(private http: HttpClient) { }
getBeer() {
return this.http.get('https://api.openbrewerydb.org/breweries')
}
}
首先引入 HttpClient
,然后通过依赖注入创建一个实例,并创建了一个方法,返回接口数据。
/src/app/app.module.ts
中引入 HttpClientModule
:
import { HttpClientModule } from '@angular/common/http'; // Add this
@NgModule({
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule // Add here
],
list.component.ts
中添加:
import { HttpService } from "../http.service";
export class ListComponent implements OnInit {
brews: Object;
constructor(private _http: HttpService) { }
ngOnInit() {
this._http.getBeer().subscribe(data => {
this.brews = data
console.log(this.brews);
})
);
}
}
list.component.html
中添加:
<h1>Breweries</h1>
<ul *ngIf="brews">
<li *ngFor="let brew of brews">
<p class="name">{{ brew.name }}</p>
<p class="country">{{ brew.country }}</p>
<a class="site" href="{{ brew.website_url }}">site</a>
</li>
</ul>
list.component.scss
中添加:
ul {
list-style-type: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
li {
background: rgb(238, 238, 238);
padding: 1em;
margin-right: 10px;
width: 20%;
height: 200px;
margin-bottom: 1em;
display: flex;
flex-direction: column;
p {
margin: 0;
}
p.name {
font-weight: bold;
font-size: 1.2rem;
}
p.country {
text-transform: uppercase;
font-size: .9rem;
flex-grow: 1;
}
}
}
最终效果:
image
网友评论