angular2 组件

首先了解angular2 组件的含义

angular2的应用就是一系列组件的集合

我们需要创建可复用的组件供多个组件重复使用

组件是嵌套的,实际应用中组件是相互嵌套使用的

组件中的数据调用可以使用inputs和outputs

一个组件可以是一种指令

一个组件可以包含前端表现及后端逻辑

一个组件可以是一个代码片段,能够独立运行

进一步理解指令

一个指令就是一个组件

一个指令可以装饰指令,用于改变DOM

一个指令可以是模板指令,可以改变element

一个实际例子

一辆车有门、方向盘、窗等等,假设车就是母组件,方向盘就是子组件

在angular2中组件是可以多级次的,那么他们间的交流就是数据交换,这种机制就是数据流

在当前angular2版本的数据绑定是单向的,父组件数据向子组件数据传递,再向子子组件数据传递

子组件可以使用event向父组件传递数据

所以我们可以说有两种方式数据绑定

我们能够通过判断ngmodel来实现这两种数据绑定方式

实例分析

myApp.ts

import {bootstrap} from 'angular2/platform/browser';

import {carComponent} from "./car.component";

bootstrap(carComponent);

这里首先说明angular入口,即我们需要启动的组件

这里看到首先要引入bootstrap,用于下面加载组件,其次引入我们需要的组件carComponent,也就是我们下面要定义的一个class

car.component.ts

///<reference path="../node_modules/angular2/typings/browser.d.ts"/>

import {Component} from 'angular2/core';

import {door} from './door.component';

@Component({

selector: "carTag",

template: `

<h3 class="titles">Mother Car Component</h3>

<input type ="text" #textInput bind-value="text" />

<button on-click="onCarChange(textInput.value)">Change</button>

<div class="child-style">

<door [textLevel1]="text" (changed)="onCarChange($event)">

</door>

</div>

`,

directives: [door],

styles:[ `

.titles {

color:#0099FF

}

.child-style {

background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">            }

`]

})

export class carComponent {

text: string="输入文字";

onCarChange(value) {

this.text ="向子组件传递数据:"+value;

}

}

door.component.ts

///<reference path="../node_modules/angular2/typings/browser.d.ts"/>

import {Component, EventEmitter} from 'angular2/core';

@Component({

selector: "door",

template: `

<h2>Child Component</h2>

<input type ="text" #textInput value="{{textLevel1}}">

<button (click)="onDoorChange(textInput.value)">Change</button>

`,

inputs: ['textLevel1'],

outputs: ['changed']

})

export class door {

textlevel: string;

changed = new EventEmitter();

onDoorChange(value) {

this.textlevel ="向父组件传递数据:"+ value;

this.changed.emit(value);

}

}

}

Car.html

<!DOCTYPE html>

<html>

<head>

<script>document.write('<base href="' + document.location + '" />');</script>

<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- CSS file -->

<link href="css/bootstrap.min.css" rel="stylesheet" />

<!-- IE polyfills, keep the order please -->

<script src="node_modules/es6-shim/es6-shim.min.js"></script>

<script src="node_modules/systemjs/dist/system-polyfills.js"></script>

<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>

<script src="node_modules/systemjs/dist/system.src.js"></script>

<script src="node_modules/rxjs/bundles/Rx.js"></script>

<script src="node_modules/angular2/bundles/angular2.dev.js"></script>

<script src="node_modules/typescript/lib/typescript.js"></script>

<!-- Agular 2 Router -->

<script src="node_modules/angular2/bundles/router.dev.js"></script>

<!-- Config Agular 2 and Typescript -->

<script>

System.config({

transpiler: 'typescript',

typescriptOptions: { emitDecoratorMetadata: true },

packages: {'app': {defaultExtension: 'ts'}}

});

System.import('app/myApp')

.then(null, console.error.bind(console));

</script>

</head>

<!-- Run the application -->

<body>

<carTag>Loading Sample...</carTag>

</body>

</html>

组件引用

第一行,目前版本的bug,所有自定义组件在当前版本下需要加入

下面引入Component,@Companent是typescript的一种注解语言,用于配置我们当前组件,具体里面有很多的参数,后面细说。

引入我们需要的组件(import)

组件配置

先看看selector,即标签,也就是我们在html中要使用的标签名称,类似于标准的html标签(如<div>,<h1>),我们知道一个component可以是一个指令,carComponent 就是一个director,通过定义selector来标识这个指令。

template:该组件的模板,可以理解为该组件的视图,在template中就可以使用刚刚定义的标签,也就是在selector中定义标签名称,方法就像使用标准html的标签一样。此处是一个内嵌的模板,使用一对“`”符号来标记模板中的内容。

在该模板中可以看到input标签中定义了一个局部变量,Angular2提供一种简单的语法将元素 映射为局部变量:添加一个以#var-开始的属性,后续的部分表示变量名, 这个变量对应元素的实例。在input的value处我们看到该值绑定了carComponent组件的一个属性,使用{{}}绑定,这是angular的一种插值绑定语法,另一种方式可使用使用一对中括号将HTML元素或组件的属性绑定到组件模型的某个表达式, 当表达式的值变化时,对应的DOM对象将自动得到更新如<input type ="text" #textInput [value]="text" />注意value后的text是carComponent的一个属性,而value是input对象的属性,还有一种表达方式你也可以使用bind-前缀进行属性绑定如<input type ="text" #textInput bind-value="text" />

该模板button中(click)代表着事件 ,使用一对小括号包裹事件名称,并绑定 到表达式,也可使用事件名称前加on-前缀如

<button on-click="onCarChange($event)">Change</button>
textInput即是前面在input中定义的局部变量代表着input的实例,onCarChange是carComponent中定义的方法,接收 一个参数,这里是为了触发text属性变化来通知子组件,当然也可以直接在input中进行定义,如

<input type ="text" #textInput bind-value="text" (change)="onCarChange(textInput.value)" />

效果是一样的。
该模板中使用了door标签,也就是我们在door组件中定义的标签,其中的textLevel1和changed是在door组件中定义的输入和输出项

组件嵌套及沟通

在car组件中的template中使用door标签,就意味着需要加入door组件,故形成了嵌套关系,那么首先需要import 引入door组件import {door} from './door.component';

在模板中我们使用door组件的door标签,那么就需要配置directives指令集

directives:指令集,注意是一个集合,也就是说在该组件中嵌入多个组件(需要先import),由于上面在模板中使用了door指令所以在该集合中必须加入door指令

我们看到在car组件中的模板是这样使用car组件的

<door [textLevel1]="text" (changed)="onCarChange($event)">

这里加入了door标签,而[textLevel1]是door标签的一个属性,可以理解为input标签的value属性 ,那么这个属性的定义需要在door组件中的inputs中加入
inputs: ['textLevel1']
表示door标签使用textLevel1来接收上级传来的数据,[textLevel1]="text"表示door组件的textlevel1属性绑定了car组件的text属性,通过这样设计就实现了父组件向子组件的数据传递。那么子组件又是如何向父组件传递数据的呢?就是使用outputs,outputs提供了一个事件的集合,利用子组件定义的事件来向上级传递数据,如(changed)=" onCarChange ($event)"中所示,(changed)是door组件定义的事件并在outputs配置中做了声明 ,此处注意调用的是父组件的事件处理函数。
outputs: ['changed']

$event是该事件相关的数据,这里就是textlevel1的值

组件定义

为了能够让其他组件能够使用所以需要export该组件,组件的定义和class一样,使用typescirpt语法,组件中可以定义属性,方法,可以有公共的也可以是私有的,如果是私有的需要加入private声明,需要注意的是如果使用了事件需要引入EventEmitter。如import {Component, EventEmitter} from 'angular2/core';
事件定义使用

changed = new EventEmitter();

使用Emit 传递事件如this.changed.emit(value);
 

组件的数据交互

Angular2相比angular1有一个很大的改变就是默认情况下的绑定是单向绑定,也是就是说视图上的数据变更不能直接更新model了,需要程序化进行更新,这样做的目的是为了提高效率,当然目前版本还保留了[(ngModel)]这种绑定方式,可以实现双向绑定。那么组件间的数据相互如何传递呢,父-〉子,子-〉父,子-〉子?

父到子的数据传递

在父组件中使用子组件就是简单的使用子组件标签方式,那么可以将子组件的一个属性绑定到父组件的一个属性上就实现了父组件数据向子组件传递。简单理解下

在父组件中定义一个子组件<child [childProperty]=”parentProperty”></child>

这很类似于在父组件中使用<input [value]=”parentProperty” ></input>

通过这种方式子组件就能够获取父组件的数据了,需要注意的是子组件需要将用于绑定的属性公布出去,即使用inputs:[‘childProperty’],这里是个数组,可以公布多个属性供外部绑定。

总结来说就是可以通过将父组件的一个属性绑定到子组件中公布的一个属性上就实现了父组件向子组件传递数据的效果。

子到父的数据传递

子组件向父组件传递数据是通过事件的方式,首先需要在子组件中定义事件,子组件的事件被触发时引发父组件的事件响应,同时将事件参数传递给父组件的响应函数,这样就完成了子组件向父组件传递数据。如下所示

<childLevel1 [parentMsg]="parentMsg" (childLevel1Changed)="OnChildLevel1MsgChanged($event)"> </childLevel1>

[parentMsg]是子组件的一个属性,而值来自父组件的parentMsg,这样实现了父组件向子组件传递parenMs数据,另外(childLevel1Changed)是子组件中定义的事件,而OnChildLevel1MsgChanged是父组件的一个事件响应函数,而$event代表着事件源。从这个例子我们分析看看数据流。下面是子组件的事件定义:

outputs: ['childLevel1Changed']
<button (click)="OnChildLevel1MsgChanged(childLevel1Text.value)" >changeChild1</button>
OnChildLevel1MsgChanged(event) {
        
        this.childLevel1Msg = event;
        this.childLevel1Changed.emit(event);
        
    }

事件的发生顺序由子组件的按钮引发交由事件处理程序,事件的参数是childLevel1Text. Value,事件处理程序将子组件定义的事件广播出去,并传递数据源,父组件检测到子组件的事件并交给父组件的事件处理程序来处理。这样就将子组件的数据传递给了父组件。

子到子的数据传递

了解了上面的方式后,那么子到子就简单了,分成子到父,再父到子。父组件在中间起到协调作用

最后,看到这些有些疑惑了,一个真实应用会有很多的数据交互,如果使用这种机制,那很难去维护这里的关系了,难道没有更好的方式去实现组件间的数据交互吗?答案是服务!

angularjs2 学习笔记(二) 组件的更多相关文章

  1. React学习笔记(二) 组件状态

    组件的状态(this.state): 组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI getIni ...

  2. Vue.js官方文档学习笔记(二)组件化应用的构建

    组件化应用的构建 组件化应用允许我们使用小型.独立和通常可复用的组件构建大型应用. Vue注册组件 Vue.component('todo-item',{template:'<li>这是个 ...

  3. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  4. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  5. Angularjs2 学习笔记

    angularjs2 学习笔记(一) 开发环境搭建   开发环境,vs2013 update 5,win7 x64,目前最新angular2版本为beta 17 第一步:安装node.js 安装nod ...

  6. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  7. muduo学习笔记(二)Reactor关键结构

    目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...

  8. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  9. amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules

    amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules 一.总结 1.am:以 am 为命名空间 2.模块状态: {命名空间}-{模块名}-{状态描述} 3.子模块: {命名空间}- ...

  10. amazeui学习笔记二(进阶开发1)--项目结构structure

    amazeui学习笔记二(进阶开发1)--项目结构structure 一.总结 1.项目结构:是说的amazeui在github上面的项目结构,二次开发amazeui用 二.项目结构structure ...

随机推荐

  1. Windows 2008 IIS7.0安装FTP教程 IIS7.5 配置多用户FTP

    一. 安装IIS.右键[我的电脑],选择[管理]打开.     选择[角色],选择[添加角色]打开.                   二. 配置DOS.输入: CACLS "%Syste ...

  2. 跟我学 NHibernate (三)

    在使用 NHibernate 时,一定要将Mapping 映射文件,也就是 xml 文件的编译方式设置成 嵌入式,这是因为在 NHibernate 启动时,它会主动的到项目的启动目录中寻找 被设置为嵌 ...

  3. phpinfo中查不到memcache信息问题

    已经安装了php的memcache扩展,可是怎么都不能通过phpinfo查询到,实际使用时提示扩展未安装.为什么呢?百般寻求解决方法,才发现主要有以下两点原因: 1.使用的php和安装扩展的php不是 ...

  4. Java基础——clone()方法浅析

    一.clone的概念 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...

  5. SQL常用日期转换

    0   或   100   (*)     默认值   mon   dd   yyyy   hh:miAM(或   PM)       1   101   美国   mm/dd/yyyy       ...

  6. docker容器服务器 - centos atomic host

    https://blog.inovex.de/docker-a-comparison-of-minimalistic-operating-systems https://github.com/rvyk ...

  7. oracle 游标示例

    declare iCount int:=0; sPath nvarchar2(200); tdzsh nvarchar2(50);begin for x in (select c.imgpath fr ...

  8. java实验报告三 敏捷开发与XP

    20145306 java 实验三 实验报告 实验内容 1.git下载结对同学的代码 2.修改结对同学的代码 3.实现代码重构 实验步骤 新建存储空间 git下载代码 将修改后的代码上传 上传结果 重 ...

  9. Dell™ SAS 5/iR 集成适配器和适配器用户指南

    http://www.sxszjzx.com/~t096/manual/sc/SAS_5ir/index.htm

  10. jquery 入门之-------jquery 简介

    什么是jquery? Jquery是一个Javascript库,通过封装原生的Javascript函数得到一套定义好的方法.它可以用个少的代码完成更多更强大更复杂的功能,从而得到开发者的青睐. So! ...