Angular2 不明真相第一个Demo例子
如果不是去年换工作接触到AngularJS,估计是不会花时间去学习这个框架的,毕竟是前端的框架,不是自己熟悉的领域。但是为了混得下去,去年就学习了AngularJS的一些用法,当时还整理了一些积累 《AnguarJS测试的实施步骤整理》。
原以为可以凑合够用应付项目开发,没想到上个月公司前端扛大旗的人就说要使用Angular2,现有的AnagularJS 1.XX版本的代码会逐步升级到Angular2。去年就听说了AngularJS已经升级了,并且跟typescript联姻了,还听说typescript的语法跟C#很类似,说什么后台程序员学Angular2没有什么问题。也没有实际去学习,但目前项目需要用到,所以最近就启动了Angular2的学习过程,不指望在短期内精通,总得在新技术落地之前自己有个基础的知识,不至于手忙脚乱,也显得自己淡定。
接着讲讲Angular2,为什么少了JS?这就是最大的升级嘛?这也是个升级,没毛病。之前AngularJS的名称用于1.XXX版本,去年7月份Angular正式发布了2.0版本,也就这里说的Angular2。2.0版本几乎是break changes,也就是说跟之前的版本不兼容了,几乎推翻重来了,所以苦逼开发者还得重复学习轮子。新版本引入了typescript,typescript是javascript的超集,通过typescript可以生成javascript代码。然后还提出了很多新的概念,比如component,import,新的module,新的指令等等。总之有得你去学习。
这里不深入分析各个模块,自己也刚了解不久,这篇博文演示用Angular2创建一个Demo例子,用于直观感受,提提学习兴趣,找找自信心。
一、准备环境
a.安装Node.js和NPM
步骤不说了,安装完成之后命令行node –v, npm -v看看版本,比如我的分别是v6.9.2和3.10.9
b.找个开发工具,这里使用visual studio code,简单快捷
二、准备项目
a.准备package.json文件
新建一个目录todo/app
mkdir –p todo/app
然后cd到todo目录,新建一个package.json文件,使用过node.js的应该知道这是干嘛的,类似于asp.net core的project.json,定义了一些依赖内容。
package.json
{
"dependencies": {
"@angular/common": "2.2.0",
"@angular/compiler": "2.2.0",
"@angular/core": "2.2.0",
"@angular/forms": "2.2.0",
"@angular/platform-browser": "2.2.0",
"@angular/platform-browser-dynamic": "2.2.0",
"reflect-metadata": "0.1.8",
"rxjs": "5.0.0-beta.12",
"zone.js": "0.6.26",
"core-js": "2.4.1",
"classlist.js": "1.1.20150312",
"systemjs": "0.19.40",
"bootstrap": "4.0.0-alpha.4"
},
"devDependencies": {
"lite-server": "2.2.2",
"typescript": "2.0.3",
"typings": "1.4.0",
"concurrently": "3.1.0"
},
"scripts": {
"start": "concurrently \"npm run tscwatch\" \"npm run lite\" ",
"tsc": "tsc",
"tscwatch": "tsc -w",
"lite": "lite-server",
"typings": "typings"
}
}
看起来又是一堆面条,这里暂时从字面意思知道三大块的意思
dependencies:运行程序需要用到的依赖组件
dveDependencies:用于开发环境的依赖组件
scripts:可在命令行运行的脚本,这里包含了TypeScript的编译器和开发时用到的HTTP server
准备了package.json之后,执行如下命令
npm install
这是讲package.json的依赖的包下载到本地,可以理解为nuget的restore,这个命令需要些时间,稍等。

下载完成之后,那么在todo目录下会新增一个node_modules目录,都是些依赖包信息。
b.配置TypeScript编译器
之前提到Angular2可用Typescript生成JS代码,这是新版的重大卖点,用typescript可以利用些高级特性生成复杂的JS代码,同时也为开发人员省去了对兼容性的考虑。
在todo目录下创建如下tsconfig.json文件
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"exclude": [
"node_modules"
]
}
c.新建一个Index.html
好了回到最原始的一个文件,还是在todo目录下,内容如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>ToDo</title> <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" /> </head>
<body>
<h1>Content will go here</h1>
</body>
</html>
到此基本项目已经准备好,在todo目录运行用visual studio code打开,目录结构应该是这样的

然后好奇这个简单的项目能运行吗,当然可以。在todo目录下运行如下命令
npm start

然后根据提供的Access URL,在浏览器打开就可以了(实际运行之后FireFox自动就开打了这个URL)

就显示一行内容而已,不过也证明了是可以运行的。
通过上面的命令行可以看到实际上是运行了一个简单的HTTP Server,这个server还会监控index.html的页面变化,并实时在浏览器自动刷新显示最新的内容。比如我们把index.html更新为如下内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>ToDo</title> <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" /> </head> <body class="m-a-1">
<h3 class="bg-primary p-a-1">Junwen's To Do List</h3>
<div class="m-t-1 m-b-1">
<input class="form-control" />
<button class="btn btn-primary m-t-1">Add</button>
</div> <table class="table table-striped table-bordered">
<thead>
<tr>
<th>Description</th>
<th>Done</th>
</tr>
</thead>
<tbody>
<tr><td>Buy Flowers</td><td>No</td></tr>
<tr><td>Get Shoes</td><td>No</td></tr>
<tr><td>Collect Tickets</td><td>Yes</td></tr>
<tr><td>Call Joe</td><td>No</td></tr>
</tbody>
</table>
</body>
</html>
那么浏览器的内容会自动更新为如下
。
三、将Angular框架引入到项目中
更新index.html文件,更新为
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>ToDo</title> <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" /> <script src="node_modules/classlist.js/classList.min.js"></script>
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.min.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> </head>
<body class="m-a-1">
<todo-app>Angular placeholder</todo-app>
</body>
</html>
这里引入了一些Angular项目需要依赖的JS文件,并且将body的内容更改成了一个自定义的标记,是不是感觉又回到了ASP.NET Core。
目前这里todo-app的标记,浏览器是没法识别和解析的,所以直接原样输出了内容

实现todo-app指令
接下来就是要实现todo-app的内容,切换到todo/app目录
a.新建model.ts文件
没错这就是我们要写的第一个typescript文件,内容如下
export class Model{
user:
items;
constructor(){
this.user = "Junwen Luo";
this.items = [
new ToDoItem("Firt Item", false),
new ToDoItem("Second Item", true),
new ToDoItem("Third Item", false),
new ToDoItem("Fourth Item", false)
];
}
}
export class ToDoItem{
action;
done;
constructor(action, done){
this.action = action;
this.done = done;
}
}
大致的意思就是新建了两个类,分别是Model和ToDoItem,然后有各自的构造方法,是不是很熟悉的套路呢。
这个语法浏览器当然不认账啦,.ts什么鬼,之前提到ts是javascript的超集,那么会在typescript编译器会将.ts文件生成对应的.js代码文件,保存.ts之后应该会生成一个model.js文件,代码如下
"use strict";
var Model = (function () {
function Model() {
this.user = "Junwen Luo";
this.items = [
new ToDoItem("Firt Item", false),
new ToDoItem("Second Item", true),
new ToDoItem("Third Item", false),
new ToDoItem("Fourth Item", false)
];
}
return Model;
}());
exports.Model = Model;
var ToDoItem = (function () {
function ToDoItem(action, done) {
this.action = action;
this.done = done;
}
return ToDoItem;
}());
exports.ToDoItem = ToDoItem;
如果代码没有自动生成,可以重新运行npm start。
b.新建一个模板,还是在app目录下,新建文件名为app.component.html
<h3 class="bg-primary p-a-1">{{getName()}}'s To Do List</h3>
<div class="m-t-1 m-b-1">
<input class="form-control" #todoText>
<button class="btn btn-primary m-t-1" (click)="addItem(todoText.value)">
Add
</button>
</div>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th></th>
<th>Description</th>
<th>Done</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of getTodoItems(); let i = index">
<td>{{i+1}}</td>
<td>{{item.action}}</td>
<td><input type="checkbox" [(ngModel)]="item.done" /></td>
<td [ngSwitch]="item.done">
<span *ngSwitchCase="true">Yes</span>
<span *ngSwitchDefault>No</span>
</td>
<td>
<button (click)="removeItem(i)">Delete</button>
</td>
</tr>
</tbody>
</table>
这里{{}}表示的是绑定的内容,应该很好理解。
这个模板提供了显示列表,添加和删除Item的功能,其中使用了*ngFor,*ngSwitch,*ngSwitchDefault,ngModel等这些指令。
ngModel是用于双向绑定
(click)是绑定单击事件
*ngFor都比较好理解,for循环嘛
c.新建app.component.ts,内容如下
import { Component } from "@angular/core";
import { Model, ToDoItem } from "./model";
@Component({
selector: "todo-app",
templateUrl: "app/app.component.html"
})
export class AppComponent {
model = new Model();
getName() {
return this.model.user;
}
getTodoItems() {
return this.model.items;
}
addItem(newItem) {
if (newItem != "") {
this.model.items.push(new ToDoItem(newItem, false));
}
}
removeItem(index) {
console.log(index);
if (index >= ) {
this.model.items.splice(index, );
}
}
}
这里创建一个组件,意思是匹配到todo-app的标记都要通过templateUrl对应的模板来解析显示。
然后还定义一个类和方法,感觉像Controller。
import的作用就是导入需要依赖的内容,类似于命名空间引入吧。
d.新建app.module.ts
上一个文件只是一个Component,当然还是不能够直接运行,需要通过一个Module来封装,更1.XXX版本的思想理念是一致的。
app.module.ts内容如下
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { AppComponent } from "./app.component";
@NgModule({
imports:[BrowserModule, FormsModule],
declarations:[AppComponent],
bootstrap:[AppComponent]
})
export class AppModule{}
e.新建main.ts
到此还不能运行了,还需要一个入口,可以理解为main方法吧。
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app.module";
platformBrowserDynamic().bootstrapModule(AppModule);
f.更新index.html文件
上面都定义好了Angular的内容,那需要加入到index.html页面中,在原有的head加入如下scripts
<script>
var paths = {
"rxjs/*": "node_modules/rxjs/bundles/Rx.min.js",
"@angular/*": "node_modules/@angular/*"
}
var packages = { "app": {} };
var angularModules = ["common", "compiler", "core", "forms",
"platform-browser", "platform-browser-dynamic"];
angularModules.forEach(function (pkg) {
packages["@angular/" + pkg] = {
main: "/bundles/" + pkg + ".umd.min.js"
};
});
System.config({ paths: paths, packages: packages });
System.import("app/main").catch(function(err){ console.error(err); });
</script>
看起来很麻烦吧,没错就是这样,到这里应该就完成了,这样html页面就跟Angular胜利会师了,看看运行的效果

CRD没有U的功能就这么简单实现,只当做第一个体验学习吧。
代码路径
https://github.com/shenba2014/ProAngular2ndExamples/tree/master/FirstAngularApp/
Angular2 不明真相第一个Demo例子的更多相关文章
- Android中Service的一个Demo例子
Android中Service的一个Demo例子 Service组件是Android系统重要的一部分,网上看了代码,很简单,但要想熟练使用还是需要Coding. 本文,主要贴代码,不对Servic ...
- demo: 全页面CSS3动画的一个参考例子
全页面CSS3动画的一个参考例子: http://wow.blizzard.cn/wow/wod-achievement/ 魔兽的一个活动页 第二页.第三页,文字进入页面 <script src ...
- angular开发者吐槽react+redux的复杂:“一个demo证明你的开发效率低下”
曾经看到一篇文章,写的是jquery开发者吐槽angular的复杂.作为一个angular开发者,我来吐槽一下react+redux的复杂. 例子 为了让大家看得舒服,我用最简单的一个demo来展示r ...
- SQL Server Reporting Service(SSRS) 第一篇 我的第一个SSRS例子
很早就知道SQL SERVER自带的报表工具SSRS,但一直没有用过,最近终于需要在工作中一展身手了,于是我特地按照自己的理解做了以下总结: 1. 安装软件结构 SSRS全称SQL Server Re ...
- 【Qt官方MQTT库的使用,附一个MqttClient例子】
Qt官方MQTT库的使用,附一个MqttClient例子 开发环境:win7 64 + Qt5.9 记录时间:2018年3月11日 00:48:42 联系邮箱: yexiaopeng1992@126. ...
- .NET Core微服务之路:让我们对上一个Demo通讯进行修改,完成RPC通讯
最近一段时间有些事情耽搁了更新,抱歉各位了. 上一篇我们简单的介绍了DotNetty通信框架,并简单的介绍了基于DotNetty实现了回路(Echo)通信过程. 我们来回忆一下上一个项目的整个流程: ...
- quartz---的一个简单例子
quartz---的一个简单例子 首先建立一个maven项目.jar工程即可.(提示:我前面有如何建立一个maven工程的总结以及maven环境的配置.) 1.建立好后点击到app中运行,--> ...
- 初识nginx之第一个demo
商城项目做了一个多月了,想到必须用到负载均衡,简单了解了一下nginx,首先分享第一个demo,五月份上线后,会继续分享一系列相关知识. 在nginx根目录下,用了一个园友的批处理文件nginx.ba ...
- springMvc的第一个demo
1.下载jar包 http://repo.spring.io/libs-release-local/org/springframework/spring/4.2.3.RELEASE/ 2.下载源码 j ...
随机推荐
- maven项目搜索依赖jar包顺序
local_repo > settings_profile_repo > pom_profile_repo > pom_repositories > setti ...
- Jquery EasyUI 各组件属性、事件详解
CSS类定义: div easyui-window window窗口样式 属性如下: 1) modal:是否生成模态窗口.tru ...
- SQL Server Job
1. SQL Server Job创建:(SQL Server 代理 - 作业)鼠标右键.新建作业. 2.[常规]选项:定义作业名称.和说明信息. 3:[步骤]选项:新建步骤 4:定义步骤名称.设置对 ...
- [C#学习笔记]你真的理解拆箱装箱吗?
学习一项新知识的时候,最好的方法就是去实践它. 前言 <CLR via C#>这本神书真的是太有意思了!没错我的前言就是这个. 装箱 首先来看下,下面这段代码 可以看到,每次循环迭代都会初 ...
- Maven新建项目产生Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resource
需要 打开并修改conf/settings.xml,添加如下内容: <!-- 设置本地仓库位置--> <localRepository>F:\maven\repository& ...
- Stacking方法详解
集成学习方法主要分成三种:bagging,boosting 和 Stacking.这里主要介绍Stacking. stacking严格来说并不是一种算法,而是精美而又复杂的,对模型集成的一种策略. 首 ...
- java 实验6 图形用户界面设计试验(2)
共两大题 窗体实现(略去测试类即 实例化自定义窗体) 小结: 1. JRadioButton 单选按钮 ButtonGroup 按钮集合(加入单选按钮) 清空选项需让ButtonGroup调用clea ...
- 洛谷P2179 [NOI2012]骑行川藏(拉格朗日乘数法)
题面 传送门 题解 看\(mashirosky\)大佬的题解吧--这里 //minamoto #include<bits/stdc++.h> #define R register #def ...
- saltstack 动态pillar实现
简介 pillar支持的数据存储方式有很多,mysql, mogo,json等.本篇介绍关于http存储方式. 首先简要说明整个流程:salt-master会去一个指定http发送get请求获取一个j ...
- QuantLib 金融计算——数学工具之随机数发生器
目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ...