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

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
H
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
量子位
博客园_首页
Vercel News
Vercel News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Forbes - Security
Forbes - Security
IT之家
IT之家
N
News and Events Feed by Topic
S
Security Affairs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Webroot Blog
Webroot Blog
Recorded Future
Recorded Future
L
LangChain Blog
Y
Y Combinator Blog
AI
AI
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google Online Security Blog
Google Online Security Blog
V2EX - 技术
V2EX - 技术
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
I
Intezer
T
Tenable Blog
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
云风的 BLOG
云风的 BLOG
C
CXSECURITY Database RSS Feed - CXSecurity.com
有赞技术团队
有赞技术团队
O
OpenAI News
P
Proofpoint News Feed
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
Blog — PlanetScale
Blog — PlanetScale

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 },
])
],