本文为作者原创,参考资料为https://angular.io/docs,如需转发请注明出处,码字不易,如有收获请点赞
这篇将通过一个简单的电子商务网站向你介绍Angular的精髓,这个电子商务网站包含商品种类,购物车,检查表单。为了帮助你立刻开始
,本向导使用了一个简单的预备好的应用,你可以交互的查看和修改这个应用(不需要创建本地工作环境)。
你是一个web开发的新手吗?
这里有大量的资源,弥补Angular文档。 Mozila的MDN文档包括HTML 和JavaScript 介绍。含有一个5分钟手稿的TypeScript的文档
各种各样的在线平台,比如Udemy 和 Codecademy, 这些都有讲到web开发基础。
创建样例项目Create the sample project
-
右边的预览界面是样例Angular应用的初始状态。它定义了一个顶部条(包括商店名和checkout控件)和产品列表的名称(这个名称将被,通过应用的数据来动态计算和更新)。
-
左边的项目展示了构成应用的源文件,包括所有的基础和配置文件。当前被选中的文件将会在中间的编辑器中被显示。
下面展示给你如何用提供的样本数据,为产品列表填写HTML template。这个能告诉你动态修改和更新网页是很容易的。
Template 语法
Angular 的模板语法延伸了HTML和JavaScript。这个部分通过对商品部分的修改介绍模板语法。
为了让你继续,下面的步骤使用了预先定义在products.ts文件中的产品数据,和product-list.component.ts
文件中的方法。
- 在
product-list
目录下,打开模板文件product-list.component.html
修改产品列表模板显示产品名字列表
列表中的每个产品以同样的方式显示,在页面中一个接着一个。为了遍历预先定义好的产品列表, 需要把*ngFor 像下面那样直接放在<div>中。
<h2>Products</h2>
<div *ngFor="let product of products">
</div>
通过*ngFor
, <div>
重复列表中的每个产品。*ngFor
是一个“结构化指令” 。结构化指令定义或者改变DOM的结构,典型的通过添加,删除和操纵附加于他们之上的元素。附带有*的指令就是结构化指令。
为了显示产品的名字,使用插值语法{{ }}
。插值表示以属性值作为文本。在<div>的内部,添加一个<h3>用于显示产品名字属性。
src/app/product-list/product-list.component.html
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
{{ product.name }}
</h3>
</div>
经过以上步骤,页面立即更新显示出每个产品的名字。
3. 为了使得每个产品名链接到产品详细介绍,添加<a>元素并且把他的title设置为产品名字,通过属性绑定[]语法,如下所示:
src/app/product-list/product-list.component.html
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
<a [title]="product.name + ' details'">
{{ product.name }}
</a>
</h3>
</div>
在之前的网页中,将指针放置于产品名,便能看到跳出的名字属性值,也就是产品名字加上详细介绍。插值{{ }}
让你渲染属性值作为文本,属性绑定[ ]让你在模板表达中使用属性值。
4. 添加产品描述。在<p>元素,使用一个*ngIf
指令以便Angular仅仅在当前产品含有description的情况下创建<p> 元素。
src/app/product-list/product-list.component.html
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
<a [title]="product.name + ' details'">
{{ product.name }}
</a>
</h3>
<p *ngIf="product.description">
Description: {{ product.description }}
</p>
</div>
这个应用现在显示每个产品的名字和描述。注意到最后一个产品不含有描述,因为产品描述属性是空的。Angular不会创建<p>元素包括单词"Description"。
5. 添加一个按钮,以便用户能够将产品共享给朋友。绑定按钮click事件到share()方法(在product-list.component.ts
)。绑定使用一系列圆括号,(),就像下面的<button>元素:
src/app/product-list/product-list.component.html
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
<a [title]="product.name + ' details'">
{{ product.name }}
</a>
</h3>
<p *ngIf="product.description">
Description: {{ product.description }}
</p>
<button (click)="share()">
Share
</button>
</div>
每个产品现在拥有了一个“Share”按钮了:
测试Button按钮:
这个app现在拥有了产品列表,和共享功能。在这个过程中你学习了Angular模板语法的5个通用功能:
Angular模板语法的全部介绍请参考 Introduction to components and templates.
组件Components
组件定义UI接口的职责范围,它能让你更重复使用一些列的UI功能。你已经建立了一个含有产品列表的组件。
一个组件由三部分组成:
- 组件类, 它能操作数据和组件功能。在前面的部分,在组件类中的产品数据和share()方法相应的处理数据和功能。
- HTML 模板, 它决定了UI。在前面的部分产品列表HTML模板显示名字,描述和为每个产品的“Share”按钮。
- 组件特有的风格,他决定了长相和直观感受。尽管产品列表没有定义风格,组件CSS存在的地方。
Angular应用由若干树形组件组成,每个组件有特有的目的和职责。上面的例子应用,拥有三个组件:
- app-root(橘黄色框)是应用shell。这个是第一个组件,他加载所有其它组件,是所有其它组件的父组件。你可以将它看成基础网页。
app-top-bar(蓝色背景)是商店名和checkout按钮。
app-product-list
(紫色框)是你之前修改的产品列表
下部分通过添加新的组件扩展app的功能---一个产品警告---作为产品列表组件的子组件。
这里有更多关于组件的信息以及他们如何和模板交互 Introduction to Components.
输入Input
目前为止,产品列表显示每个产品的名字和描述。产品列表组件也定义了一个产品属性,他包含了定义在从products.ts中的产品阵列中为每个产品导入的数据。
下一步是创建一个新的警告功能,他能以产品作为输入。这个警告核对产品价格,如果价格超过700美元,显示一个‘Notify Me’按钮,让用户在产品在售卖过程中签名。
1. 创建一个新的产品警告组件。
用鼠标右击app目录,然后使用Angular Generator生成新的组件,取名为product -alerts。
Generator创建了为组件的每个部分创建了起始文件:
product-alerts.component.ts
product-alerts.component.html
product-alerts.component.css
2.打开 product-alerts.component.ts
.
src/app/product-alerts/product-alerts.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product-alerts',
templateUrl: './product-alerts.component.html',
styleUrls: ['./product-alerts.component.css']
})
export class ProductAlertsComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
a. 注意@Component()装饰器。它表明后面的类是一个组件。它提供了组件的metadata,包括它的selector,teamplates和styles。
- Selector 标识组件。当Selector表现为HTML网页的元素,Selector就是你给Angular组件取的名字。通常,Angular组件selectors以app-前缀开始,以组件名结尾。
- template和style文件名参考了StackBlitz产生的HTML和CSS文件。
b. 组件定义同时导出类,ProductAlertsComponent,这个类主要是负责组件的功能的。
3. 创建新的产品警告组件为了接受产品作为输入:
a. 从 @angular/core
导入 Input
src/app/product-alerts/product-alerts.component.ts
import { Component, OnInit } from '@angular/core';
import { Input } from '@angular/core';
b. 在ProductAlertsComponent
类定义中,定义一个以@Input()作为装饰器的名字叫product的属性。装饰器@Input()预示从父组件,产品列表组件,传递入属性值
src/app/product-alerts/product-alerts.component.ts
export class ProductAlertsComponent implements OnInit {
@Input() product;
constructor() { }
ngOnInit() {
}
}
4. 定义新产品警告组件视图。
打开product-alerts.component.html
模板,将按钮以“Notify Me”替换占位符,这样当产品价格超过700美元后,按钮将会被显示。
src/app/product-alerts/product-alerts.component.html
<p *ngIf="product.price > 700">
<button>Notify Me</button>
</p>
5. 以产品列表组件的子组件显示新的产品警告组件。
a.打开product-list.component.html
b.为了包括新的组件,需要使用它的selector,app-product-alerts,作为HTML 元素。
c.使用属性绑定,传递当前的产品作为输入到组件
src/app/product-list/product-list.component.html
<button (click)="share()">
Share
</button>
<app-product-alerts
[product]="product">
</app-product-alerts>
新的产品警告组件以产品列表的产品作为输入。通过哪个输入,警告组件就会基于产品价格显示或者隐藏“Notify Me”按钮。比如Phone XL价格超过700美元,因此“Notify Me”按钮出现在Phone XL上。
参考Component Interaction 以便获得更多关于从父到子组件的数据传递的更多信息,拦截和处理来自于父组件的值,检测和处理输入属性值的变动。
Output输出
为了使得“Notify Me”按钮工作,你需要配置两个东西:
- 产品警告组件,这个是为了当用户点击“Notify Me”时,产生一个事件。
- 产品列表组件,这个是为了处理事件。
1. 打开 product-alerts.component.ts
.
2. 从 @angular/core
导入 Output
和 EventEmitter
:
src/app/product-alerts/product-alerts.component.ts
import { Component } from '@angular/core';
import { Input } from '@angular/core';
import { Output, EventEmitter } from '@angular/core';
3.在组件类,定义一个属性,这个属性命名为notify且以@Output()
作为装饰器,另外再定义EventEmitter()实例。这个允许当notify属性值改变时,Product警告组件发送一个事件。
src/app/product-alerts/product-alerts.component.ts
export class ProductAlertsComponent {
@Input() product;
@Output() notify = new EventEmitter();
}
4.在产品警告模板,product-alerts.component.html,更新
"Notify Me"按钮,通过事件绑定的方法,目的是为了调用notify.emit()
方法。
src/app/product-alerts/product-alerts.component.html
<p *ngIf="product.price > 700">
<button (click)="notify.emit()">Notify Me</button>
</p>
5. 下一步,定义当用户按下button按钮后,该发生什么样的行为。在product-list.component.ts定义一个onNotify()方法,与share()
方法类似:
src/app/product-list/product-list.component.ts
export class ProductListComponent {
products = products;
share() {
window.alert('The product has been shared!');
}
onNotify() {
window.alert('You will be notified when the product goes on sale');
}
}
6. 最终,更新产品列表组件,目的是为了获得产品警告组件的输出。
在product-list.component.html,绑定app-product-alerts
组件(这个组件主要是显示"Notify Me"按钮)到onNotify()
产品列表组件的方法。
src/app/product-list/product-list.component.html
<button (click)="share()">
Share
</button>
<app-product-alerts
[product]="product"
(notify)="onNotify()">
</app-product-alerts>
7. 尝试下 "Notify Me" 按钮:
祝贺你,你完成了第一个Angular app!
你创建了一个基本的在线商店,他拥有产品列表,“Share”按钮,“Notify Me”按钮。你已经学习了Angular的基础:组件和模板语法。同时你也学习了组件类和模板的交互,以及组件之间是如何通信的。