初识Angular2

Angular 2 是Google推出的一个跨平台全终端的框架
主要有八大架构组成,分别是:
module (模块)
component (组件)
template (模板)
Metadata (元数据)
data binding (数据绑定)
directive (指令)
service (服务)
dependency injection (依赖注入)
这几个构架,可以用一张图展示下之间的关系

我们去写一个Angular应用:用Angular扩展语法写HTML模板,写组件类去管理这些模板,用服务添加应用逻辑,用模块打包组件和服务。
说了这些概念性的东西你可能还是有点懵,没关系,以上内容只是让你对Angular有个大致的印象。因为,它玩来玩去就是围绕以上图片提到的几个概念展开的,接下来我们通过具体的环境搭建来了解下,Angular2是如何运行的。

环境搭建

mkdir demo
cd demo
npm init

根据npm init,创建package.json文件,创建后去掉不必要的字段,添加你所需要导入的包以及运行时的一些命令:

{
  "name": "demo","version": "1.0.0","description": "","scripts": {
    "postinstall": "./node_modules/.bin/typings install"
  },"author": "","license": "ISC","dependencies": {
    "@angular/common": "~2.1.0","@angular/compiler": "~2.1.0","@angular/core": "~2.1.0","@angular/forms": "~2.1.0","@angular/http": "~2.1.0","@angular/platform-browser": "~2.1.0","@angular/platform-browser-dynamic": "~2.1.0","@angular/router": "~3.1.0","@angular/upgrade": "~2.1.0","angular-in-memory-web-api": "~0.1.5","bootstrap": "^3.3.7","core-js": "^2.4.1","reflect-Metadata": "^0.1.8","rxjs": "5.0.0-beta.12","zone.js": "^0.6.25"
  },"devDependencies": {
    "ts-loader": "^0.8.2","typescript": "^2.0.3","typings": "^1.4.0","path": "^0.12.7","webpack": "^1.13.2","webpack-dev-server": "^1.16.1"
  }
}

简单解释下:
postinstall:来进行安装后的脚本处理
dependencies 是运行时所需要的依赖;
devDependencies 是开发时所需要的依赖,
@angular 是 Angular 的核心库,Angular2 将它分成了很多包,这样方便开发者灵活的按需引入。
@angular/common: 常用的那些由 Angular 开发组提供的服务、管道和指令
@angular/compiler: Angular 的 模板编译器 。 它会理解模板,并且把模板转化成代码,以供应用程序运行和渲染。 开发人员通常不会直接跟这个编译器打交道,而是通过 platform-browser-dynamic 或离线模板编译器间接使用它。
@angular/core:框架中关键的运行期部件,每一个应用都需要它。 包括所有的元数据装饰器: Component 、 Directive ,依赖注入系统,以及组件生命周期钩子。
@angular/platform-browser : 与 DOM 和浏览器相关的每样东西,特别是帮助往 DOM 中渲染的那部分。 这个包还包含 bootstrapStatic 方法,用来引导那些在产品构建时需要离线预编译模板的应用程序。
@angular/platform-browser-dynamic : 为应用程序提供一些 提供商 和 bootstrap 方法,以便在客户端编译模板。不要用于离线编译。 我们使用这个包在开发期间引导应用,以及引导 plunker 中的范例。
@angular/upgrade : 一组用于升级 Angular 1 应用的工具。
angular-in-memory-web-api: 一个 Angular 的支持库,它能模拟一个远端服务器的 Web API ,而不需要依赖一个真实的服务器或发起真实的 HTTP 调用。 对演示、文档范例和开发的早期阶段 ( 那时候我们可能还没有服务器呢 ) 非常有用。
reflect-Metadatarxjszone.js core-js这些都是为 Angular 提供核心功能支持。
reflect-Metadata:Angular和TypeScript共享的一个依赖。为了使用 ES7风格的装饰器准备的,就像@Component 。
core-js: javascript的一个标准库实现,包含了大量ES2015,ES2016的ES5实现。
rxjs: 一个Reactive Programming(响应式)JavaScript实现。这里对她的依赖是因为angular2支持多种数据更新模式,比如:flux、Rx.js。
zone.js: 用来对异步任务提供Hooks支持,使得在异步任务运行之前/之后做额外操作成为可能。在angular2里的主要应用场景是提高脏检查效率、降低性能损耗。
webpack-dev-server 是支持 webpack 的静态服务器调试工具,它可以实时监控项目中文件,文件改动后使浏览器自动刷新或进行热替换,我们的项目将运行在这个小型服务器上。
ts-loader 是 webpack 将 TypeScript 编译成 ES5 的编译器,本文里 我们使用 TypeScript 来写例子,它也是 Angular 官方推荐的开发语言。
typings 是 TypeScript 定义的文件管理系统.

创建其他的配置文件

配置文件tsconfig.json,(定义 TypeScript 编译成 ES5 的参数):
`
touch tsconfig.json
`

{
  "compilerOptions": {
    "target": "es5","module": "commonjs","moduleResolution": "node","sourceMap": true,"emitDecoratorMetadata": true,"experimentalDecorators": true,"removeComments": true,"noImplicitAny": true,"declaration": false
  }
}

配置文件typings.json:
一些js库扩展了JavaScript的特性和语法,但是TypeScript编译器并不识别,
通过typings.json配置可以辅助IDE,给出有智能的提示信息,以及重构的依据。
因此需要在typings.json文件中配置TypeScript类型定义文件(文件名后缀为.d.ts)
touch typings.json

{
  "globalDependencies": {
    "es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504"
  }
}

现在运行 npm install 安装 package.json 里所有的依赖包,过程可能会有些慢(如果你开了 VPN 就不存在这问题),这里推荐使用淘宝镜像命令加快安装速度
npm install --registry=https://registry.npm.taobao.org/
安装完,你的项目目录应该是这样的

如果在运行 npm install 之后没有出现 typings 目录,你就需要通过命令手动安装它:
npm run typings install

创建应用入口

在项目目录中创建 app 子目录,接着在 app 目录下创建 app.module.ts,也就是目前项目的根模块。
(Angular提倡的文件命名方式是这样的:组件名称.component.ts ,服务命名为: 服务名称.service.ts,模块: 模块名称.module.ts,大家在编码中尽量遵循Google的官方建议。 )

mkdir app
touch app/app.module.ts

在刚创建的 app.module.ts 文件中添加下面代码:

// zone 为异步任务提供hook支持,主要应用于提高脏检查效率和降低性能损耗
// reflect-Metadata 为Decorator提供反应射API
import 'zone.js/dist/zone';
import 'reflect-Metadata';

// 引入NgModule装饰器
import { NgModule } from '@angular/core';

// 引入浏览器模块
import { browserModule } from '@angular/platform-browser';

@NgModule({
    imports: [ browserModule ]
})

export class AppModule {}

NgModules 把 Angular 应用组织成了一些功能相关的代码块。 Angular 本身也被拆成了一些独立的 Angular 模块。 这让你可以只导入你应用中所需的 Angular 部件,以得到较小的文件体积。每个 Angular 应用都至少有一个模块: 根模块 ,在这里它叫做 AppModule 。
这个文件是整个应用的入口,由于应用需要运行在浏览器中,所以需要从 @angular/platform-browser 中导入browserModule,并将它添加到 imports 数组中,我们需要使用browserModule 浏览器模块,提供浏览器加载页面所需要的关键服务(Service)和指令(Directive),这个模块是所有需要在浏览器中跑的应用都必须引用的。
@(装饰器)是一种特殊的类型声明,它可以被附加到类声明,方法,属性或参数上,这里我们不做具体介绍。

创建组件,并添加到应用中

每个 Angular 应用都至少有一个根组件,整个应用由一个个组件组成,而组件化(Component)则是 Angular 的核心灵魂。

创建组件 AppComponent,即文件 app.component.ts,在其中添加代码:
touch app/app.component.ts

import { Component } from '@angular/core';

// 为 AppComponent 组件类添加注解
@Component({
  selector: 'my-app',template: '<h1>My First Angular App</h1>'
})

export class AppComponent {}

@Component装饰器 会把一份 元数据 关联到 AppComponent 组件类上

selector 用来为该组件的 HTML 元素指定简单的 CSS 选择器
template 用来告诉 Angular 如何渲染该组件的视图
class AppComponent 之所以是空的,因为我们的例子暂时不需要应用逻辑。

编辑 app.module.ts 文件,导入 AppComponent ,并把它添加到 NgModule 装饰器中的 declarations 和 bootstrap 字段:

// zone 为异步任务提供hook支持,主要应用于提高脏检查效率和降低性能损耗
// reflect-Metadata 为Decorator提供反应射API,注意:Decorator是ES6的提案
import 'zone.js/dist/zone';
import 'reflect-Metadata';

// 引入NgModule装饰器
import { NgModule } from '@angular/core';

// 引入浏览器模块
import { browserModule } from '@angular/platform-browser';
//引入AppComponent组件
import {AppComponent} from './app.component';
@NgModule({
    imports: [ browserModule ],declarations:[AppComponent],bootstrap:[AppComponent]
})

export class AppModule {}

declarations列出了应用中的顶层组件,包括引导性组件AppComponent
bootstrap指明哪个组件为引导性组件

启动应用文件

创建 main.ts 让 Angular 加载这个启动文件,在其中添加如下代码:
touch main.ts

// 引入启动器
import { platformbrowserDynamic } from '@angular/platform-browser-dynamic';
 
// 引入入口文件
import { AppModule } from './app.module';
 
// 启动应用
const platform = platformbrowserDynamic();
platform.bootstrapModule(AppModule);

为什么要分别创建 main.ts 、应用模块 和应用组件的文件呢?

因为应用的引导过程与 创建模块或者 展现视图是相互独立的。

创建应用的宿主页面 index.html
touch index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <Meta charset="UTF-8">
    <Meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Angular2 QuickStart</title>
</head>
<body>
    <!-- 对应 @Component({ selector: 'my-app',... }) -->
    <my-app></my-app>

    <!-- 编译打包后的文件 -->
    <script src="dist/bundle.js"></script>
</body>
</html>

创建webpack.config.js

我们使用 webpack 作为编译打包工具,就需要创建 webpack.config.js,
touch webpack.config.js

var path = require('path');

module.exports = {
    entry: {
        main: './app/main.ts'
    },output: {
        path: path.resolve(__dirname,'dist'),publicPath: '/dist/',filename: 'bundle.js'
    },module: {
        loaders: [
            {
                test: /\.ts$/,loader: 'ts'
            }
        ]
    },// require 文件时可省略后缀 .js 和 .ts
    resolve: {
        extensions: ['','.js','.ts']
    },// 配置 webpack-dev-server
    devServer:{
        historyApiFallback: true,hot: true,inline: true,port: 3000 // 修改端口,一般默认是8080
    }
};

修改package.json在其中添加start命令:

"scripts": {
    "start": "webpack-dev-server --inline --hot --colors --progress","postinstall": "./node_modules/.bin/typings install"
  },

一切就绪,先不急着启动 webpack-dev-server,初学者经常遇到的坑,关于 webpack-dev-server 无法让浏览器在代码修改后进行热替换,首页要确保是否全局安装了 webpack-dev-server,如果没有就运行下面命令:
npm install webpack-dev-server -g --registry=https:\\registry.npm.taobao.org
更重要的是 webpack-dev-server 只会将静态文件打包在内存中 而非你的磁盘里 这是为了方便开发环境调试,所以初学者会疑惑为什么运行了 webpack-dev-server,dist 文件夹下确无文件产生,想产生文件就运行 webpack。

ok!运行项目

npm start
打开浏览器 localhost:3000,就会看到我们的第一个angular2应用了

简单的数据绑定

我们来修改下现在页面上的内容,改为程序员常见的hello world,并且我要让hello world变成红色,在AppComponent中添加一个属性title,用angular2自带的插值表达式来展示title的内容:
<h1>Hello {{title}}</h1>
整个代码:

import { Component } from '@angular/core';

// 为 AppComponent 组件类添加注解
@Component({
  selector: 'my-app',template: '<h1>Hello {{title}}</h1>',styles:['h1{color:red}']
})

export class AppComponent {
    title='World';
}

styles顾名思义,这个就是样式的定义。当然我们也可以使用styleUrls来定义样式文件的路径。
这里我们将h1内容变为红色,我们多次提到Angular2是组件化的,组件之间是不会相互影响,也就是说我们对当前组件定义的样式只会在当前组件对应的模板内生效。

好了,我们保存一下,页面上就能看到对应的变化。
可是这样,title还是我自己定义的,我们要改动还是需要到代码里面去改,如果我给一个输入框,输什么就显示什么,并且hello保持不变?
首先,我们向页面加入一个input框,用angular2自带的模板语法#给input定义一个变量
<h1>Hello {{title}}</h1><input type="text" #userRef (keyup)="onKeyup1(userRef.value)">
这个模板引用变量名叫userRef,在<input>元素内声明,它引用<input>元素本身。 使用userRef获得输入元素的value值,并通过插值表达式把它显示在<h1>标签中。
输入触发input的keyup事件,在angular2中,对于元素的事件绑定,我们会对目标事件会用()起来,属性绑定对目标属性用[]包起来,我们给keyup事件绑定了一个方法onKeyup1,这个方法用来将用户输入的值赋给title

export class AppComponent {
    title='World';
    onKeyup1(userInput:string){
        //这是typescript的写法,定义你的参数为string类型,并在调用的时候做检查
        this.title=userInput;
    }
}

保存更改的内容你会发现,我们实现了之前想要的效果;这个时候我们回过头来看最开始的那张图,看看angular2中的八大构架,大概能理解几个,我想除了依赖注入,其他的大致都有了了解,对于angular是如何运作的应该清楚了,那就动手试试吧!

初识Angular2的更多相关文章

  1. iOS推送通知适用于Dev而不是Enterprise Distribution

    本网站上没有其他问题,我已经能够找到实际上提出了Dev将工作的原因,但企业分布不会.为什么归档总是使aps环境生产?

  2. ios – testflight库和Xcode 5没有变化现在说“ld:找不到-lTestFlight的库”

    我已经创建了几个月的应用程序,突然Xcode5不想构建它.它只是抱怨以下错误.如果我理解它可以,它会抱怨testflight,但我几周没有改变它.它完美地编译了它.我不得不说我已经尝试将AdobeADMS跟踪库添加到项目中.然后,出现链接器错误.任何提示?

  3. 如何在ios swift项目中为dev n prod使用两个不同的GoogleService-info.plist文件?

    我需要使用两个不同的GoogleService-info.plist来处理dev和prod构建,目前我只是通过在编辑方案中更改“构建配置”来分离dev和prod,但现在我需要有两个不同的.plist文件dev和prod用于处理谷歌分析,pushwoosh等,解决方法对于这种情况,您需要在Dev和Prod的项目中使用带有diffbundleid的不同Targets.之后,您可以链接GoogleSer

  4. openstack安装liberty--安装对象存储服务swift

    通常使用CACHE技術提高性能Accountservers賬戶服務,管理對象存儲中的賬戶定義。Containerservers容器服務,在對象存儲中管理容器或文件夾映……Objectservers對象服務,在存儲節點管理實際的對象,比如文件。Wsgimiddleware處理認證,通常使用OPENSTACKIdentityswiftclient為用戶提供命令行接口使用RESTAPIswift-init初始化和構建RING文件腳本swift-recon一個命令行工具,用於檢索群集的各種度量和測試信息。

  5. (Cross-)编译Swift for Raspberry PI

    Swift现在是开源的.有没有人试过编译Swift的RaspBerryPI?我开始做,但我的8GBSD卡似乎太小了;)是否可以从Ubuntu交叉编译?写Swift打开你最喜欢的文本编辑器,编写一个程序并保存它:编译它并运行它:而已!

  6. Swift 3 dev快照中的POST请求给出了“对成员’dataTask的模糊引用(with:completionHandler :)’

    编辑:我注意到有人在我之后写了这个问题的副本.这里的答案是更好的答案.使用URLRequest结构.在Xcode8中工作正常:另外,出现此错误的原因是URLSessionAPI具有相同的名称方法,但每个都采用不同的参数.因此,如果没有明确的演员,API将会混淆.我认为这是API的命名错误.发生此问题,代码如下:

  7. Android Studio是否支持用于Android UI设计的AngularJS?

    我对AndroidStudio有疑问:AS在设计XML文件时是否支持AngularJS代码,例如:对于小动画或效果?

  8. android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2

    我正尝试使用Angularjs(使用IonicFramework)通过GoogleOAuth2从我的Phonegap应用程序登录.目前我正在使用http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html进行登录.但是当我使用Angular-UI-RouterforIonic时,它正在创建非常

  9. 针对不同环境的不同Android构建

    我希望能够构建和安装我的应用程序的多个版本(同时),针对不同的环境,如开发,暂存和生产.AndroidManifest.xml中的软件包名称似乎是这里的主要障碍,因为它是唯一标识应用程序的内容.我认为可以简单地在com.mydomain.prod,com.mydomain.staging和com.mydomain.dev之间切换或某种类似的约定,但到目前为止,我还没有运气的包装结构对于这种方法.我

  10. android – 如何在Google Play商店中打开开发者页面(market://)

    ),但我在AndroidDeveloper页面上找不到它.解决方法您只需调用market://dev?id=xxx即可例如.:我希望,这适合您的需求!

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部