前言:

  本系列在前面两篇文章,介绍了Zone.js和angular2的基础概念。而后对于ng2的学习,还是由官方的 Tour of Heroes 开始。

以下内容经过提炼和个人理解,当然也会有不正确的地方,欢迎指正。有兴趣的朋友,可以自己开始ng2之旅,再结合本篇文章一起理解。

ng2的配置比较麻烦,任意的引入包可能导致一些报错,建议直接官方下载 quickStart 

ng2 将所有api分成7个类型,在查阅api的时候,可以多留意一下他们的类型,便于理解

 @Component

  @Component 申明一个应用程序可重用的UI组件,可以通过bootstrap实例化,也可以通过它本身directives属性相互实例化调用。

/* app.component.ts */
import {Component} from '@angular/core'; @Component({
selector: 'app-component',
template: `<div>{{title}}</div>` })
export class AppComponent{
title = 'Tour of Heroes';
}
/* main.ts */
 import {bootstrap} from '@angular/platform-browser-dynamic'
 import {AppComponent} from './app.component'  bootstrap(AppComponent)
//index.html

<body>  <app-component></app-component>  </body>

/* 最终页面渲染 */
  <body>     <app-component>       <div>Tour of Heroes </div>     </app-component>   </body>

  @Component 会为组件创建一个shadow DOM,将选中的模板加载到shadow DOM,创建所有配置的注入对象。

bootstrap 引导运行@Component时,会先根据@Component 的selector找到dom,并新建一个子注射器,通过一个新Zone实例进行变化检测,

创建一个shadow DOM并载入到dom节点汇总,实例化组件,最后初始化提供的数据。

shadow dom:

  在ng2的文档里,提及了shadow dom。可以参考文章:Shadow DOM:基础

shadow dom能让dom和css样式做到有作用域划分,可以相互独立,样式不相互影响。
而浏览器对shadow dom的支持并不好,但是ng2用其他方式,实现了类似shadow dom的功能。

比如,当@Component配置了styles属性,在组件实例化的时候,style会被载入到head

        

  如上图,实际我们的style原本写的是h1选择器,ng在后面加上了属性选择器[_ngcontent-hvh-1]。
在组件的根dom,ng也会加上[_ngcontent-hvh-1]此属性。
  通过一个属性选择器,ng2自动为我们隔离了style的作用域。

          

每个组件都将会加入一个特定的属性,属性后面的数字按照载入顺序累加: [_ngcontent-hvh-1] -> [_ngcontent-hvh-2] ......

@Input&@Output:

  使用@input绑定标签属性,创建组件通信的单向输入流。需要引入组件:import { Input } from '@angular/core';

“英雄之旅”例子:

/* A */
import { Input } from '@angular/core';
@Component({
selector: 'bank-account',
template: `
Bank Name: {{bankName}}
Account Id: {{id}}
`
})
class BankAccount {
@Input() bankName: string;
@Input('account-id') id: string;
// this property is not bound, and won't be automatically updated by Angular
normalizedBankName: string;
}
/* B */
@Component({ selector: 'app', template: ` <bank-account bank-name="RBC" account-id="4747"></bank-account> `, directives: [BankAccount] }) class App {} bootstrap(App);

  在一个指令组件的类里使用@Input() 对一个变量进行申明,被申明的变量可以通过指令的属性进行单向数据绑定。

@Input 有一个参数,绑定dom的属性名,如上面代码: @Input('account-id') id: string;

dom属性名account-id和类的id变量进行了绑定,<bank-account account-id="4747">

  未带参数的属性名默认用变量名 @Input() bankName: string;    <bank-account bank-name="RBC">

这样就实现组件之间的通信和绑定了。

在angular1中,directive中定义属性scope,达到scope作用域之间的数据绑定,和angular2中的@Input功能类似

scope : {
bankName : "=",
accountId : "="
}
<directive bank-name="RBC" account-id="4747"></directive>
@Output和@Input相反
OnInit&constructor
OnInit和 constructor都能实现初始化时候执行,constructor执行在ngOnInit之前。但他们的概念不同。
import {OnInit} from '@angular/core';
export class AppComponent implements OnInit{
constructor(){
//do something
}
ngOnInit(){
//do something
}
}

route:
配置路由,需要引入 RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS 。
  • RouteConfig用于定义路由配置
  • ROUTER_DIRECTIVES提供指令( [routerLink]<router-outlet> )
  • ROUTER_PROVIDERS 提供路由服务
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';

@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<a [routerLink]="['Heroes']">Heroes</a>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES],
providers: [
ROUTER_PROVIDERS,
HeroService
]
})
@RouteConfig([
{
path: '/heroes',
name: 'Heroes',
component: HeroesComponent
}
])

  [routerLink]用于指定载入链接,会对应 @RouteConfig 的 name 属性,

找到 name 之后修改路由,并显示相应UI组件,最终载入到<router-outlet>标签下。

使用router-outlet,UI组件将会自己创建selector标签,将组件加载到router-outlet标签下。

      

默认路由&路由传参:

@RouteConfig([
{
path: '/detail/:id',//可以通过此方式传参
name: 'HeroDetail',
component: ComponentA,
useAsDefault: true //设置默认路由,错误访问地址都将访问默认路由
}
])
如上代码:ComponentA 要接收参数,需要导入RouteParams
import { RouteParams } from '@angular/router-deprecated';
RouteParams是一个class,ComponentA 初始化时候,
constructor(private routeParams: RouteParams)进行定义,
在constructor或者ngOnInit方法体里,使用 this.routeParams.get('id') 进行参数获取。
import { RouteParams } from '@angular/router-deprecated';

export class ComponentA{
constructor(private routeParams: RouteParams){
console.log("id:", this.routeParams.get('id'))
}
}

通过Router手动跳转页面:

import { Router } from '@angular/router-deprecated';

class xxx{
  constructor(private router:Router){}
  go(){
    this.router.navigate(['HeroDetail', { id: this.id }]);//参数1路由名称,参数2参数
  }
  
}


事件绑定:

绑定一个事件流,在组件之间通信。
自定义事件open,在 “组件A” 中定义一个事件 open , 通过 “组件B” 的标签属性绑定 open , 通过 “组件B” 触发

//Component A
@component {
template: '<b (open)="open($event)"></b>'
}
class A{
open(){
    console.log('done');
  }
}
//Conponent B
import { Component, EventEmitter, Output } from '@angular/core';
class B{
@Output() open= new EventEmitter();
this.open.emit();//emit也可以传参
}
(open)="open($event)",自定义open方法里必须要带上$event,否则不会执行,至于为什么之后再研究。
如果是(click) 这种绑定浏览器默认事件,(click)="open()",就可以不用传$event。

小结:

  在使用ng2或者说使用ts开发的ng2时,会写入更多的代码用于申明、依赖、定义类型等,比如import,@Input,@Output,在开发的时候会觉得很麻烦,

但是这种严格的规范带来的就是更高的可维护性,比如import虽然可能会写很多,但是后期维护某个组件的时候就能很清楚的知道当前组件使用了哪些模块。

编译的时候angular2遵循严格模式,能够帮助避免一些代码错误和不规范。

  这趟 “英雄之旅“ 仅仅是一个开始,见识了angular2核心、常用的api、组织结构和代码风格。还有很多内容是需要去专研和理解。

虽然涉及不深,但是已经明显感觉到,一些angular1中的不足,在angular2中已经不存在了。



 

“英雄之旅”见闻和小结----angular2系列(三)的更多相关文章

  1. ng1和ng2的部分对比----angular2系列(四)

    前言: angular2相比angular1做了革命性的改变.对于开发者来说,我们知道它框架的实现上改变极大.我们看到代码也能发现它写法上变化很大,似乎完全是另一个东西. 但是当我们真正去写下去的时候 ...

  2. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  3. VSTO之旅系列(三):自定义Excel UI

    原文:VSTO之旅系列(三):自定义Excel UI 本专题概要 引言 自定义任务窗体(Task Pane) 自定义选项卡,即Ribbon 自定义上下文菜单 小结 引言 在上一个专题中为大家介绍如何创 ...

  4. angular2系列教程(一)hello world

    今天我们要讲的是angular2系列教程的第一篇,主要是学习angular2的运行,以及感受angular2的components以及模板语法. 例子 这个例子非常简单,是个双向数据绑定.我使用了官网 ...

  5. C# 互操作性入门系列(三):平台调用中的数据封送处理

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  6. [转]C# 互操作性入门系列(三):平台调用中的数据封送处理

    参考网址:https://www.cnblogs.com/FongLuo/p/4512738.html C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列( ...

  7. 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp专家

    系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...

  8. WCF学习之旅——第一个WCF示例(三)

    第五步:创建客户端 WCF应用服务被成功寄宿后,WCF服务应用便开始了服务调用请求的监听工作.此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据.接下来我们来创建客户端 ...

  9. Web 开发人员和设计师必读文章推荐【系列三十】

    <Web 前端开发精华文章推荐>2014年第9期(总第30期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

随机推荐

  1. Python之路第一课Day10--随堂笔记(异步IO\数据库\队列\缓存)

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SS ...

  2. centos7安装mysql5.7

    http://jingyan.baidu.com/album/93f9803f010d8fe0e56f555e.html?picindex=15

  3. Linux 系统的初始化配置

      1.零时配置网卡IP地址 2.配置永久生效IP地址   需要进如 cd /etc/sysconfig/network-scripts  找到网卡文件编辑 3.零时主机名的更改. 4.永久主机名的更 ...

  4. js生成二维码 中间有logo

    描述: jquery.qrcode.js 是一个能够在客户端生成矩阵二维码QRCode 的jquery插件 ,使用它可以很方便的在页面上生成二维条码.此插件是能够独立使用的,体积也比较         ...

  5. SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输

    SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输 微软高兴地宣布所有主流SQL Server客户端驱动和SQL Server发行版已经支持T ...

  6. 介绍.NET 开发必备工具 .NET Portability Analyzer

    随着.NET的原来越开放,不仅仅是开源这么简单了,也意味着.NET程序员要关注越来越多的平台,涵盖.NET Mic Framework, Xamarin,Mono,.NET等等,从windows到li ...

  7. ABP理论学习之审计日志

    返回总目录 本篇目录 介绍 配置 通过特性开启/关闭 注意 我项目中的例子 介绍 维基百科说: "审计跟踪(也叫审计日志)是与安全相关的按照时间顺序的记录,记录集或者记录源,它们提供了活动序 ...

  8. UWP开发之控件:用WebView做聊天框

    目录 说明 WebView存在的价值 使用WebView的几个重要技巧 使用WebView做的聊天框 说明 大家都知道,无论是之前的Winform.WPF还是现在的IOS.Android开发中,都存在 ...

  9. 你所不知道的JavaScript数组

    相信每一个 javascript 学习者,都会去了解 JS 的各种基本数据类型,数组就是数据的组合,这是一个很基本也十分简单的概念,他的内容没多少,学好它也不是件难事情.但是本文着重要介绍的并不是我们 ...

  10. 《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述

    微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...