“英雄之旅”见闻和小结----angular2系列(三)
前言:
本系列在前面两篇文章,介绍了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系列(三)的更多相关文章
- ng1和ng2的部分对比----angular2系列(四)
前言: angular2相比angular1做了革命性的改变.对于开发者来说,我们知道它框架的实现上改变极大.我们看到代码也能发现它写法上变化很大,似乎完全是另一个东西. 但是当我们真正去写下去的时候 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- VSTO之旅系列(三):自定义Excel UI
原文:VSTO之旅系列(三):自定义Excel UI 本专题概要 引言 自定义任务窗体(Task Pane) 自定义选项卡,即Ribbon 自定义上下文菜单 小结 引言 在上一个专题中为大家介绍如何创 ...
- angular2系列教程(一)hello world
今天我们要讲的是angular2系列教程的第一篇,主要是学习angular2的运行,以及感受angular2的components以及模板语法. 例子 这个例子非常简单,是个双向数据绑定.我使用了官网 ...
- C# 互操作性入门系列(三):平台调用中的数据封送处理
好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...
- [转]C# 互操作性入门系列(三):平台调用中的数据封送处理
参考网址:https://www.cnblogs.com/FongLuo/p/4512738.html C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列( ...
- 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp专家
系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...
- WCF学习之旅——第一个WCF示例(三)
第五步:创建客户端 WCF应用服务被成功寄宿后,WCF服务应用便开始了服务调用请求的监听工作.此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据.接下来我们来创建客户端 ...
- Web 开发人员和设计师必读文章推荐【系列三十】
<Web 前端开发精华文章推荐>2014年第9期(总第30期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
随机推荐
- HTML5将图片转化成字符画
HTML5将图片转化成字符画 字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢?HTML5让这个可能变成了现实,通过canvas,可以很轻松实现这个功能.其实原理很简单:扫描图片相应位置 ...
- css3新属性object-fit,对页面img处理
1.http://my.xueh5.com/xh5639998239/detail-3661.html 针对其进行深度讲解推荐 http://www.zhangxinxu.com/wordpress/ ...
- Node.js Ubuntu下安装
安装 Node.js 依次执行以下指令: sudo apt-get update sudo apt-get install -y python-software-properties python g ...
- linux用户管理(二)
最简单的加入用户useradd 用户名这样的命令不好,因为会新建一个组为这个用户. 这里提到一个问题,为什么普通用户没有/etc/shadow的写权限却能修改自己的密码呢. 因为 /user/bin/ ...
- Android再学习
1.点击事件的几种实现方式 Button Btn1 = (Button)findViewById(R.id.button1);//获取按钮资源 Btn1.setOnClickListener(new ...
- 科学计算软件——Octave安装
Octave是一个旨在提供与Matlab语法兼容的开放源代码科学计算及数值分析的工具,是Matlab商业软件的一个强有力的竞争产品. 参考:[ML:Octave Installation] Gener ...
- hadoop2.2编程:MRUnit测试
引用地址:http://www.cnblogs.com/lucius/p/3442381.html examples: Overview This document explains how to w ...
- 【HTML5】Web Audio API打造超炫的音乐可视化效果
HTML5真是太多炫酷的东西了,其中Web Audio API算一个,琢磨着弄了个音乐可视化的demo,先上效果图: 项目演示:别说话,点我! 源码已经挂到github上了,有兴趣的同学也可以去st ...
- ASP.NET MVC 过滤器(三)
ASP.NET MVC 过滤器(三) 前言 本篇讲解行为过滤器的执行过程,过滤器实现.使用方式有AOP的意思,可以通过学习了解过滤器在框架中的执行过程从而获得一些AOP方面的知识(在顺序执行的过程中, ...
- 跨域获取json一些理解[腾讯电商数据的拉取方式]
如何跨域获取json数据源?我们都知道要有callback,具体callback是如何工作的呢?如果服务器端不接收callback,我们是不是就没有办法处理了呢?读完本文后相信你会有一个大体的了解. ...