“英雄之旅”见闻和小结----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中已经不存在了。



 
时间: 2024-10-05 11:18:00

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

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

今天我们要讲的是ng2的路由系统. 例子 例子是官网的例子,包含一个“危机中心”和“英雄列表”,都在一个app中,通过路由来控制切换视图.还包含了promise的用法,服务的用法等多个知识点. 源代码: https://github.com/lewis617/angular2-tutorial/tree/gh-pages/router 运行方法: 在根目录下运行: http-server 引入库文件设置base href 路由并不在ng2中,需要我们额外引入,另外我们需要设置base href,

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

原文:VSTO之旅系列(三):自定义Excel UI 本专题概要 引言 自定义任务窗体(Task Pane) 自定义选项卡,即Ribbon 自定义上下文菜单 小结 引言 在上一个专题中为大家介绍如何创建Excel的解决方案,相信大家通过从上面一个专题之后了解了Excel的对象模型,以及Office两种解决方案的,看完上一个专题之后,肯定很多朋友想为Excel自定义属于自己的UI界面,例如,有这样的一些疑问——是否可以使用VSTO来自定义选项卡呢? 是否可以自定义上下文菜单的呢?如果你也有这些疑问

angular2系列教程(一)hello world

今天我们要讲的是angular2系列教程的第一篇,主要是学习angular2的运行,以及感受conponents以及模板语法. http://lewis617.github.io/angular2-tutorial/hellowold/ 例子 这个例子非常简单,是个双向数据绑定. 运行方法: 全局安装http-server npm install -g http-server 公共部分 公共部分就是你直接复制粘贴拿去用的部分,包括: 1.index.html 2.lib 3.app/main.t

angular2系列教程(六)升级装备、pipe

今天,我们要讲的是angualr2的pipe这个知识点,但是在这之前我们需要升级一下我们的装备,因为之前的装备太“寒酸”了. 例子 这个例子包含两个pipe,一个是stateful,一个是stateless,是直接复制官方的例子.本例子还包含了我对AngularClass/angular2-webpack-starter这个牛逼starter的改写,我会详细讲解配置. 源代码 没有测试 AngularClass/angular2-webpack-starter 这里面包含了Angular 2 (

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

传送门 C#互操作系列文章: C#互操作性入门系列(一):C#中互操作性介绍 C#互操作性入门系列(二):使用平台调用调用Win32 函数 C#互操作性入门系列(三):平台调用中的数据封送处理 C#互操作性入门系列(四):在C# 中调用COM组件 本专题概要 数据封送介绍 封送Win32数据类型 封送字符串的处理 封送结构体的处理 封送类的处理 小结 一.数据封送介绍 看到这个专题时,大家的第一个疑问肯定是--什么是数据封送呢?(这系列专题中采用假设朋友的提问方式来解说概念,就是希望大家带着问题

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

好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------------------------------------------------------------------- C#互操作系列文章: C#互操作性入门系列(一):C#中互操作性介绍 C#互操作性入门系列(二):使用平台调用调用Win32 函数 C#互操作性入门系列(三):平台调用中的数据封

Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送

Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送,写这个系列真的很要命,你要去把他们的API文档大致的翻阅一遍,而且各种功能都实现一遍,解决各种bug各种坑,不得不说,极光推送真坑,大家使用还是要慎重,我们看一下极光推送的官网 https://www.jpush.cn/common/ 推送比较使用,很多软件有需要,所以在这个点拿出来多讲讲,我们本节

Exchange 2013SP1和O365混合部署系列三

继续,基本上大多数都是截图,在某些地方,会有一些提示. 下面就是和本地域进行同步,主要用到的是Dirsync工具. 全都是下一步. 继续下一步. 继续下一步. 这里输入的就是O365的管理员账号.也就是当时注册的那个. 本地管理员账号. 继续下一步. 开始自动配置. 开始同步本地的账户.到WAAD. 图上我们可以看到同步状态. 继续下面的操作,激活已同步的用户. 根据需要选择. 有印象没?安装同步工具的时候选的那个密码同步的选项. 先到这吧,下篇开始在本地Exchange 2013 SP1上配置

Spring Data 系列(三) Spring+JPA(spring-data-commons)

本章是Spring Data系列的第三篇.系列文章,重点不是讲解JPA语法,所以跑开了JPA的很多语法等,重点放在环境搭建,通过对比方式,快速体会Spring 对JPA的强大功能. 准备代码过程中,保持了每个例子的独立性,和简单性,准备的源码包,下载即可使用.如果,对JPA语法想深入研究的话,直接下载在此基础上进行测试. 前言 Spring Data 系列(一) 入门:简单介绍了原生态的SQL使用,以及JdbcTemplate的使用,在这里写SQL的活还需要自己准备. Spring Data 系