惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
H
Hackread – Cybersecurity News, Data Breaches, AI and More
月光博客
月光博客
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
H
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
T
Troy Hunt's Blog
宝玉的分享
宝玉的分享
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Schneier on Security
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
B
Blog
The GitHub Blog
The GitHub Blog
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Register - Security
The Register - Security
F
Fortinet All Blogs
爱范儿
爱范儿
L
LINUX DO - 热门话题
V
Vulnerabilities – Threatpost
Scott Helme
Scott Helme
Schneier on Security
Schneier on Security
N
News and Events Feed by Topic
Last Week in AI
Last Week in AI
D
Docker
Application and Cybersecurity Blog
Application and Cybersecurity Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Spread Privacy
Spread Privacy
The Hacker News
The Hacker News
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
P
Privacy International News Feed
O
OpenAI News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Recent Commits to openclaw:main
Recent Commits to openclaw:main
S
Securelist
Google Online Security Blog
Google Online Security Blog
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
Martin Fowler
Martin Fowler

qubeijun的博客

言语理解与表达 父亲往事-我儿子叫冬冬 公务员行测答题顺序及用时及答题技巧 判断推理 数量关系 冬甜夫妇5-10-5-21日本蜜月行程安排回归总结篇(无图片) 冬甜夫妇5.10-5.21日本蜜月行程安排计划篇 5.1 小贝壳疫苗计划 100DAYS 父亲往事-猴牤大爷的“帽子” 父亲往事-姨妈家的葡萄架 父亲往事-十五的月饼 父亲往事-姑妈的压岁钱 父亲往事-母亲的缝纫机父亲的锯 父亲往事-家属来队 父亲往事-新兵连的生活 父亲往事-村北的槐树林 父亲往事-小贝壳 公务员面试 系统架构设计师 图形推理 数学运算 父亲往事-惊蛰 资料分析 父亲往事-偷吃西红柿有绝窍 父亲往事-毯子衣服 父亲往事-水壶煮鸡蛋 父亲往事-煎饼蘸香油 系统架构设计师论文 软件设计师 父亲往事-大哥 资料分析-旧 基于grafana的监控部署 mysql数据库定时备份&运行日志定时清理 各种问题解决答案汇总 Alibaba Cloud Toolkit的使用说明 Dojo简单入门 vue基础知识点总结 java正则表达式收集 java处理时间和日期api java常用的io,输入输出 java常见集合汇总 java调试代码不再用system.out.println(),用日志来调试程序 java常用工具类总结 java常用字符串操作总结 python之pymysql增删改查mysql数据库 词性标注集 python获取当前文件夹下的所有的文件名 mysql数据库操作总结 (翻译)Understanding LSTM Networks (翻译)Understanding Convolutional Neural Networks for NLP (翻译)传统和深度学习模型在文本分类中的应用综述与基准 小木虫论坛-学术科研互动平台爬虫 solr命令(持续更新) python json读写操作 python pip安装包镜像 python数字进度条 抓取维基百科分类索引下某一分类下的子分类及其分类下的页面(仅限词条) python3循环读取excel文件并写入json python3 requests动态网页post提交数据 python+selenium搜狗微信主页抓取 2017年5月25日 2017年5月18日 2017年5月17日 2017年5月15日 2017年5月16日 2017年5月14日 2017年5月13日 2017年5月12日 2017年5月11日 2017年5月10日 2017年5月9日 2017年5月8日 2017年5月7日 2017年5月6日 2017年5月5日 2017年5月4日 2017年5月3日 2017年5月2日 2017年5月1日 儿子的信-2013年7月9日 儿子的信-2013年7月8日 儿子的信-2011年11月26日 儿子的信-2010年8月16日 儿子的信-2010年1月2日
Angular简单入门
qubeijun · 2020-03-17 · via qubeijun的博客

发表于|更新于|前端

|总字数:2.4k|阅读时长:10分钟|浏览量:|

由于未来项目需要(PM说的),于是展开了一个新的技能树,在此记录Angular入门学习过程。今天从0开始接触。

话外:

AngularJS和Angular的区别

老的angular也就是1.x版本的称为AngularJS,新的2.x以上的版本重命名为Angular。所以肯定上手新的Angular。

开始安装

每个框架一般都有自己的脚手架,方便进行开发,使开发人员专注于开发,而不花费时间在环境配置上。

Angular CLI就是Angular的脚手架。

全局安装Angular CLI(前提是已经安装node.js)

1
npm install -g @angular/cli

创建一个新的、基本的 Angular 项目

1
2
3
ng new my-first-project      #新建名为my-first-project项目
cd my-first-project #打开my-first-project
ng serve -o #启动项目并从默认浏览器打开

开始学习

根据官方例子进行学习

一、模版语法

1、通过*ngFor进行遍历操作,并用插值语法 {{}}进行显示。

1
2
3
4
5
6
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
{ { product.name }}
</h3>
</div>

2、鼠标悬停预览详情

1
2
3
4
5
6
7
8
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
<a [title]="product.name + ' details'">
{ { product.name }}
</a>
</h3>
</div>

3、添加商品说明。在< p >标签上,用*ngIf指令,这样 Angular 只会在当前商品有描述信息的情况下创建这个< p >元素。

1
2
3
4
5
6
7
8
9
10
11
<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>

4、添加一个按钮,以便让用户可与朋友分享商品。

把button的click事件绑定到我们替你定义好的share()方法上(位于product-list.component.ts)。

事件绑定是通过把事件名称包裹在圆括号()中完成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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>

小结:

该应用现在具有商品列表和共享功能。Angular 模板语法的五个常用特性:

  • *ngFor

  • *ngIf

  • 插值 {{}}

  • 属性绑定 []

  • 事件绑定()

二、组件 

  • app-root(橙色框)是应用的外壳。这是第一个组件,也是所有其它组件的父组件。可以把它想象成一个基础页面。

  • app-top-bar(蓝色背景)是商店名称和结帐按钮。

  • app-product-list(紫色框)是你在上一节中修改过的商品列表。

1、创建一个新组件:product-alerts,包含三个主要文件:样式文件css,模版文件html,类文件ts。

1
ng generate component product-alerts

用命令生成的文件都是有默认模版的,规定以下带注释的都是后添加的。 

文件product-alerts.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Component, OnInit } from '@angular/core';

//从angular导入Input装饰器
import { Input } from '@angular/core';
//从angular导入Ouput装饰器、EventEmitter事件发射器
import { Output, EventEmitter } from '@angular/core';

@Component({
selector: 'app-product-alerts',
templateUrl: './product-alerts.component.html',
styleUrls: ['./product-alerts.component.css']
})
export class ProductAlertsComponent implements OnInit {

//定义一个带 @Input() 装饰器的 product 属性。
//@Input() 装饰器指出其属性值是从该组件的父组件商品列表组件中传入的。
@Input() product;

//用 @Output() 装饰器和一个事件发射器 EventEmitter() 实例定义一个名为 notify 的属性。
//这可以让商品提醒组件在 notify 属性发生变化时发出事件。
@Output() notify = new EventEmitter();

constructor() { }
ngOnInit() {
}
}

文件product-alerts.component.html

1
2
3
4
5
<!-- 如果商品价格超过 700 美元就要显示出来的“通知我”按钮。 -->
<p *ngIf="product.price > 700">
<!-- 用事件绑定更新“Notify Me”按钮,以调用 notify.emit() 方法。 -->
<button (click)="notify.emit()">Notify Me</button>
</p>

文件product-list.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Component } from '@angular/core';
import { products } from '../products';

@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
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');
}
}

将product-alert作为组件写入product-list

文件product-list.component.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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>

<!-- product-alert组件 -->
<!-- 修改商品列表组件以接收商品提醒组件的输出。 -->
<app-product-alerts
[product]="product"
(notify)="onNotify()">
</app-product-alerts>
</div>

三、路由 

将商品详情建立为组件,通过路由跳转访问详情。

注册路由

文件app.module.ts

1
2
3
4
5
6
7
8
9
10
11
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: '', component: ProductListComponent },

//添加一个商品详情路由,该路由的 path 是 products/:productId
{ path: 'products/:productId', component: ProductDetailsComponent },
])
],

文件product-list.component.html

1
2
3
4
5
6
7
8
9
<!-- 把商品索引赋值给productId -->
<div *ngFor="let product of products; index as productId">
<h3>
<!-- 设置路由链接 -->
<a [title]="product.name + ' details'" [routerLink]="['/products', productId]">
{ { product.name }}
</a>
</h3>
</div>

新建商品详情组件

1
ng generate component product-details

文件product-details.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
//从 ../products 文件导入 products 数组
import { products } from "../products";

@Component({
selector: "app-product-details",
templateUrl: "./product-details.component.html",
styleUrls: ["./product-details.component.css"]
})
export class ProductDetailsComponent implements OnInit {
//定义 product 属性,并把它加入构造函数括号中作为参数,以便把 ActivatedRoute 注入到构造函数中
product;
constructor(
private route: ActivatedRoute,
) {}

//在 ngOnInit() 方法中订阅了路由参数,并且根据 productId 获取了该产品
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.product = products[+params.get("productId")];
});
}
}

文件product-details.component.html

1
2
3
4
5
6
<h2>Product Details</h2>
<div *ngIf="product">
<h3>{ { product.name }}</h3>
<h4>{ { product.price | currency }}</h4>
<p>{ { product.description }}</p>
</div>

现在,当用户点击商品列表中的某个名字时,路由器就会导航到商品的不同网址。

用商品详情组件代替商品列表组件,并显示商品详情。

四、管理数据

服务是 Angular 应用的重要组成部分。

在 Angular 中,服务是一个类的实例,它可以借助 Angular 的依赖注入系统来让应用中的任何一个部件都能使用它。

服务可以让你在应用的各个部件之间共享数据。对于在线商店,购物车服务就是存放购物车的数据和方法的地方。

1、定义购物车服务

1
ng generate service cart

文件cart.service.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { Injectable } from "@angular/core";
import { HttpClient } from '@angular/common/http';

@Injectable({
providedIn: "root"
})
export class CartService {
//定义一个 items 属性来把当前商品的数组存储在购物车中
items = [];
constructor() {}
//把商品添加到购物车方法
addToCart(product) {
this.items.push(product);
}
//返回购物车商品方法
getItems() {
return this.items;
}
//清除购物车商品的方法
clearCart() {
this.items = [];
return this.items;
}
}

2、使用购物车服务

文件product-details.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";

import { products } from "../products";

//导入购物车服务
import { CartService } from "../cart.service";

@Component({
selector: "app-product-details",
templateUrl: "./product-details.component.html",
styleUrls: ["./product-details.component.css"]
})
export class ProductDetailsComponent implements OnInit {
product;

//通过把购物车服务注入到这里的 constructor() 中来注入它
constructor(
private route: ActivatedRoute,
private cartService: CartService
) {}

//定义 addToCart() 方法,该方法会当前商品添加到购物车中
addToCart(product) {
window.alert('Your product has been added to the cart!');
this.cartService.addToCart(product);
}

ngOnInit() {
this.route.paramMap.subscribe(params => {
this.product = products[+params.get("productId")];
});
}
}

文件product-details.component.html

1
2
3
4
5
6
7
8
<h2>Product Details</h2>
<div *ngIf="product">
<h3>{ { product.name }}</h3>
<h4>{ { product.price | currency }}</h4>
<p>{ { product.description }}</p>
<!-- 添加一个标签为“Buy”的按钮,并把其 click() 事件绑定到 addToCart() 方法 -->
<button (click)="addToCart(product)">Buy</button>
</div>

3、创建购物车页面 

1
ng generate component cart

 文件cart.component.html

1
2
3
4
5
6
<h3>Cart</h3>

<div class="cart-item" *ngFor="let item of items">
<span>{ { item.name }}</span>
<span>{ { item.price | currency }}</span>
</div>

4、为购物车组件添加路由(URL 模式)

文件app.module.ts

1
2
3
4
5
6
7
8
9
10
11
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
//为组件 CartComponent 添加一个路由,其路由为 cart
{ path: 'cart', component: CartComponent },
])
],