Angular 版本
Angular 4.0并不是在原有基础上改的,而是一个完全重写的版本,不同于Angular 1.5。
Angular 2.0之前的版本,统一称为AngularJs。Angular 2.0之后的版本就称之为Angular。
第一章:简介
1、AngularJs的优点
- 模板功能强大(自带AngularJs 指令,拥有强大数据双向绑定能力,减少J Query对dom的操作以及代码量)。
- 比较完善的前端MVC框架(包含模板、数据双向绑定、路由、模块化、服务、过滤器、依赖注入等等所有的功能)。
- 引入了Java的一些概念(例如依赖注入和单元测试,能够很容易写出复用代码)。
2、AngularJs的一些问题
- 性能(对于脏数据的检查的提升)
- 路由(整个框架的核心模块)
- 作用域(把执行环境和浏览器的环境分开)
- 表单验证
- Javascript语言
- 学习成本。需要学习大量的概念。
AngularJs的核心就是组件,且很容易编写。
3、AngularJs的新特性
- 全新的命令行工具AngularCLI。提供很多方面的功能,比如生成一个新项目的骨架,运行自动化单元测试等。
- 服务器端渲染。可以使原本需要10S才能加载完的单页应用在1S之内加载完成,并且可以对单页应用进行优化。
- 移动和桌面的兼容。可以创建跨平台的手机应用。
4、AngularJs架构
AngularJs是典型的MVC架构。
- 如下是AngularJs架构。
用户看到的是视图,也就是html等内容,用户会和视图进行一些交互,比如点击鼠标,或者输入一些数据,这些动作会被视图(view
)传递给控制器(controller
),控制器会根据用户的输入去修改或查询底层的数据模型,这时,底层的数据模型可能会与服务器产生一些数据交互,以获取或更新数据信息,然后底层数据模型的这些改变,会通过数据绑定
机制反馈到视图层,使用户看到自己做所的操作所产生的效果。
- 下面是Angular的架构。
对于Angular,整个应用就是一个组件树,用户可以通过执行一些操作从一个组件路由到另一个组件,从一个组件到另一个组件时用户的页面会有些变化,因为激活的组件不一样了。
用户可以与某个组件进行交互,而这些交互由组件进行处理,组件可以通过依赖注入的方式引入一些服务,并用这些服务来处理用户的操作或者与服务器进行通讯。
5、AngularJs与React对比
React的优点
速度。
与其他框架相比,React采用了一种特立独行的操作DOM的方式,也就是我们常说的虚拟DOM方式。在性能方面,在更新的时候,会先检查更新虚拟,再和实际的DOM进行比较更新,所以,和Angular比,react一方面更新的DOM次数少,另一方面是更新的数据少,因此速度比较快。FLUX架构。
ReactJs更关注UI的组件化和数据的单向更新,提出了flask架构的新概念。并且,在ReactJs中可以直接使用ES6的语法,然后通过webpack的工具编写出兼容的ES5。以前AngularJs不具备这些东西,但是现在Anguarl都已具备,比如组件化、数据的单向中心、ES6的支持。服务器端渲染
这个也是以前AngularJs没有,而React具有。
6、AngularJs与Vue对比
Vue的优点
简单。
容易上手
Vue作者尤雨溪灵活。
性能。
尺寸比较小,用了类似于虚拟DOM的方式处理组件,所以速度也很快。Vue主导。
Vue是由个人主导的,而Angular是Google主导,而且使用的是微软开发的TypeScript语言。只关注Web。
Vue是一个只关注Web的框架。Angular实现了一个多层次的抽象,可以开发web项目,也可以开发客户端应用(也就是面向安卓等)。服务器端渲染。
Vue只能靠第三方的库进行渲染,而Angular有官方提供的服务器端渲染支持,可以解决Vue无法解决的一些纯前端的一些痛点。
第二章:开始学习Angular
1、Angular程序架构
组件
是Angular应用的基本构建块,你可以把组件理解为一段带有业务逻辑和数据的html。
一个父组件可以包含多个子组件。
组件可以调用服务。服务
用来封装可重用的业务逻辑。
服务可以互相调用,也就是服务可以调服务。指令
允许你向Html元素添加自定义行为。模块
用来将应用中不同部分组织成一个Angular框架可以理解的单元。
2、Angular开发环境
【安装Nodejs】(http://nodejs.cn/download/)
-
【安装Angular CLI】
Nodejs安装完成之后,直接使用以下命令npm install -g @angular/cli
进行安装就可以。安装完成之后可以使用
ng -v
命令来查看安装结果。显示如下图:
如果你的PC上安装过nodejs或npm,可能会涉及到版本过低的问题,更新的话就自行百度吧!
- 【安装WebStorm】(https://www.jetbrains.com/webstorm/)
WebStorm是前端 的一个比较有名的开发工具,也可以使用Sublime。
和WebStorm同产的还有一个后端开发工具PyCharm,这里作为了解。
3、新建项目
ng new auction //auction为项目的名称
执行这个命令之后,angular命令行工具工具会在当前所在路径下新建一个名为auction
的项目。
4、组件的必备元素
- 装饰器@Compoent()
- 模板Template
- 控制器Controller
模板和控制器通过数据绑定来讲控制器中的数据绑定到模板上,以上是称之为一个属性所必须的所有东西。当然还有一些可选的注入对象,比如:
- 输入属性@Inputs()——允许你在组件树中传递数据。
- 提供器providers——用来做依赖注入的。
- 生命周期钩子Lifecycle Hooks——一个组件从创建到销毁的过程中有多个钩子可以被用来触发执行各种业务逻辑,例如在组件被实例化以后可以执行一段初始化逻辑代码,从后台读取一些数据到组件里面去。
- 样式表Styles——组件可以关联一些样式表到模板中。
- 动画Animations——方便我们创建与组件相关的动画效果,如淡入淡出等等。
- 输出属性@Outputs——和前面的输入属性是相对的,用来定义一些其他属性可能会感兴趣的事件,或者用来在组件间共享数据。
5、启动Angular过程介绍
要解释Angular的启动过程,要明白三个问题:
- 启动时加载了哪个页面?
- 启动时加载; 哪些脚本?
- 这些脚本做了什么事?
我们先来看看前面两个问题
在.angular.cli.json
文件里面,有一个apps的数组,数组里面有一些属性,其中:
"index": "index.html"
,
index指向src里面的index.html文件,这个文件是angularJs启动时加载的页面"main": "main.ts",
angularJs启动时加载的脚本,main.ts负责引导angular脚本的启动
main.ts的文件内容:
//前面是导入几个必要的库
import { enableProdMode } from '@angular/core'; //用来关闭angular的开发者模式
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module'; //整个应用的主模块
import { environment } from './environments/environment'; //导入环境配置
if (environment.production) { //判断,如果是生产环境,就关闭开发者模式
enableProdMode();
}
//调用bootstrapModule方法,传入AppModule作为启动模块来启动应用。这里是整个应用程序的起点。
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
在执行到AppModule时,angular会分析AppModule要依赖哪些模块,并加载那些模块,我们可以在app/app.module.ts
里面看到所需要导入的模块。然后看这些模块需要哪些模块,以此类推,直到加载完所有的模块。加载完成后,angular会在index.html
中寻找启动模块指定的主组件(也就是app.module.ts
里面的bootstrap: [AppComponent]
)对应的css选择器(app.component.ts
里面的app-root
)。
启动过程了解之后,我们看一下实际的效果:
-
点击右上角选择Edit Confiogurations,如下图
-
然后添加一个npm命令。
注意:Scripts里面可选的选项是在上图所示的package.json文件里面定义的,上图package.json展示了基本选项。这里选择Start命令。 -
点击右上角
Run auction start(或shift +F10)
启动服务。
这里可能要稍微等一等,当然,如果你的电脑速度够快,它也能立刻完成加载启动的过程。
最终执行好的程序会通过 http://localhost:4200/ 暴露出来。看到
bundle is now VALID
或是webpack: Compiled successfully.
就是已经有效了。现在,如果没有什么问题,就可以通过 http://localhost:4200/来访问你的页面了。如果不能正常加载页面,你可以返回去检查一下前面的步骤有没有出错。 当前开发环境会自动侦测src目录下面的改变,任何对src目录下文件的改变,都会使服务器自动加载修改后的文件,然后刷新页面。
下面是运行界面:
到这里,angular的启动过程就已经完成了,我们接着往下来!
6、开发准备
一般来说,我们会用到bootstrap和jQuery,下面就以安装这两个库为例。
首先设置第三方的依赖。
一般情况下,如果要在angular项目中使用第三方类库, 需要一下几步
-
第一步就是把第三方库安装到本地
可以直接在webstorm的命令行下安装,也可以直接在命令行安装。 安装jquery:npm install jquery --save //--save是把jquery这个依赖记到当前的package.json文件里面。
安装bootstrap:
npm install bootstrap --save
下载完成后,它会把你的安装包放在node_modules文件夹里,同时会在package.json加入对应的依赖。
-
第二步是把安装的库引到项目里面去
引到项目里的时候,就需要修改.angular-cli.json
文件,把刚刚安装的第三方类库添加到scripts
里面,用bootstrap主要使用它的样式,所以把bootstrap.css加入到styles
里面。"styles": [ "styles.css", "../node_modules/bootstrap/dist/css/bootstrap.css" ], "scripts": [ "../node_modules/jquery/dist/jquery.js", "../node_modules/bootstrap/dist/js/bootstrap.js" ],
添加之后,这几个文件就被添加到项目里了。
注意:typeScript是不认识jquery的$符号的,它必须引入对应的类型描述文件才可以使用,安装的时候只需要在前面加一个@types
就可以。安装类型描述文件的目的就是让typescript代码认识jquery和bootstrap,这样就可以在typescript里面调jquery和bootstrap的东西。npm install @types/jquery --save-dev //安装jquery的类型描述文件 npm install @types/bootstrap --save-dev //安装bootstrap的类型描述文件
下面开始来写代码
angular框架的设计目标中,最主要的设计目标之一就是帮助开发人员开发出可重用的开发组件。现在很多特性都是为这个目标服务的。所以在开发angular应用时也要用一种组件化的思路来思考要解决的问题。
利用组件来实现下面这个页面。
angular命令行工具提供了自动生成组件的功能。通过命令行在auction目录下生成一个组件,app那个组件命令行工具在创建项目的时候就已经创建了,把其他需要的六个组件生成出来就可以了。
- 依次执行以下命令,生成各个组件(navbar、footer、search、carouse、product、stars):
- ng g componet navbar //导航栏组件
- ng g componet footer //页脚组件
- ng g componet search //搜素表单组件
- ng g componet carouse //轮播组件
- ng g componet product //商品展示组件
- ng g componet stars //星级评价组件
以上每个命令执行时都会生成css、html、ts以及测试文件spec.ts,同时还会更新app.module.ts文件。执行完以上命令后,app这个目录下会多出六个文件夹,然后在app.module.ts
文件里面,在declarations
的这个属性里多了刚声明的六个组件。
到这里呢,就已经用angular的命令行工具把我们要编写的代码写出来了。接下来只需要一个个编写组件就可以,在这个过程中我们会一步步强化组件的概念。
7、 开发app组件
前面说了这么多,终于要开始写代码了,上面我们把页面分成了七个组件,现在我们从最基础的app组件开始,首先来改一下app.component.html
文件
每一个组件都可以用app.module.ts
文件里面selector
声明的标签来引用。
根据上面的目标页面设置下面的布局,具体的bootstrap的标签的使用,你可以参考官网的Bootstrap全局样式
app.component.html
<app-navbar></app-navbar>
<div class="container">
<div class="row">
<div class="col-md-3">
<app-search></app-search>
</div>
<div class="col-md-9">
<div class="row">
<app-carousel></app-carousel>
</div>
<div class="row">
<app-product></app-product>
</div>
</div>
</div>
</div>
<app-footer></app-footer>
app.component.css
.carousel-container{
margin-bottom: 40px;
}
8、开发navbar和footer组件
navbar.component.html
<nav class="navbar navbar-inverse navbar-fixed-top">
<!--inverse黑底白字-->
<!--fixed-top是固定在顶部-->
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="#" class="navbar-brand">在线竞拍</a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li><a href="#">关于我们</a></li>
<li><a href="#">联系我们</a></li>
<li><a href="#">网站地图</a></li>
</ul>
</div>
</div>
</nav>
footer.component.html
<div class="container">
<hr>
<div class="row">
<div class="col-lg-12">
<p>慕课网Angular入门实战</p>
</div>
</div>
</div>
这两个组件比较简单
9、开发search和carousel组件
search.component.html
<form name="searchForm" role="form">
<div class="form-group">
<label for="productTitle">商品名称</label>
<input type="text" id="productTitle" placeholder="商品名称" class="form-control">
<label for="productPrice">商品价格</label>
<input type="text" id="productPrice" placeholder="商品名称" class="form-control">
<label for="productCategory">商品类别</label>
<select name="" id="productCategory" class="form-control"></select>
</div>
<div class="form-group">
<button type="button" class="btn btn-primary btn-block">搜索</button>
</div>
</form>
carousel.component.html
<div class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li class="active"></li>
<li></li>
<li></li>
</ol>
<div class="carousel-inner">
<div class="item active">
<img class="slide-image" src="http://placehold.it/800x300/">
</div>
<div class="item">
<img class="slide-image" src="http://placehold.it/800x300/">
</div>
<div class="item">
<img class="slide-image" src="http://placehold.it/800x300/">
</div>
</div>
<a href="javascript:$('.carousel').carousel('prev')" class="left carousel-control">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a href="javascript:$('.carousel').carousel('next')" class="right carousel-control">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
carousel.component.css
.slide-image{
width: 100%;
}
10、开发product组件
product.component.html
<div *ngFor="let product of products" class="col-md-4 col-sm-4 col-lg-4">
<div class="thumbnail">
<img [src]="imgUrl">
<div class="caption">
<h4 class="pull-right">{{product.price}}</h4>
<h4><a href="">{{product.title}}}</a></h4>
<p>{{product.desc}}</p>
</div>
<div>
<app-stars [rating]="product.rating"></app-stars>
</div>
</div>
</div>
product.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
private products: Array<Product>;
private imgUrl = 'http://placehold.it/320x150';
constructor() { }
ngOnInit() {
this.products = [
new Product(1, '第一个商品', 1.99, 3.5, '这是第一个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品', '硬件设备']),
new Product(2, '第二个商品', 2.99, 2.5, '这是第二个商品,是我在学习慕课网Angular入门实战时创建的', ['图书']),
new Product(3, '第三个商品', 3.99, 4.5, '这是第三个商品,是我在学习慕课网Angular入门实战时创建的', ['硬件设备']),
new Product(4, '第四个商品', 4.99, 1.5, '这是第四个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品', '硬件设备']),
new Product(5, '第五个商品', 5.99, 3.5, '这是第五个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品']),
new Product(6, '第六个商品', 6.99, 2.5, '这是第六个商品,是我在学习慕课网Angular入门实战时创建的', ['图书']),
];
this.products.push(new Product(7, '第六个商品', 7.99, 1.5, '这是第七个商品,是我在学习慕课网Angular入门实战时创建的', ['图书']))
}
}
export class Product{
constructor(
public id: number,
public title: string,
public price: number,
public rating: number,
public desc: string,
public categories: Array<string>
){
}
}
11、开发stars组件
stars.component.html
<p>
<span *ngFor="let star of stars" class="glyphicon glyphicon-star glyphicon-star-empty"
[class.glyphicon-star-empty]="star"></span>
<span>{{rating}}星</span>
</p>
stars.component.ts
import {Component, Input, OnInit} from '@angular/core';
@Component({
selector: 'app-stars',
templateUrl: './stars.component.html',
styleUrls: ['./stars.component.css']
})
export class StarsComponent implements OnInit {
@Input()
private rating = 0;
private stars: boolean[];
constructor() { }
ngOnInit() {
this.stars = [];
for (let i = 1; i <= 5; i++){
this.stars.push(i > this.rating);
}
}
}
小结
Angular的环境搭建及基本的组件开发到这里就差不多了。简单的在线竞拍网站也构建完成,接下来会对Angular的每个功能进行详细的讲解,然后对在线竞拍网站进行改造。