angular2 组件
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-color:#00ffff
}
`]
})
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,事件处理程序将子组件定义的事件广播出去,并传递数据源,父组件检测到子组件的事件并交给父组件的事件处理程序来处理。这样就将子组件的数据传递给了父组件。
子到子的数据传递
了解了上面的方式后,那么子到子就简单了,分成子到父,再父到子。父组件在中间起到协调作用
最后,看到这些有些疑惑了,一个真实应用会有很多的数据交互,如果使用这种机制,那很难去维护这里的关系了,难道没有更好的方式去实现组件间的数据交互吗?答案是服务!
angular2 组件相关推荐
- Angular2 组件通信
1. 组件通信 我们知道Angular2应用程序实际上是有很多父子组价组成的组件树,因此,了解组件之间如何通信,特别是父子组件之间,对编写Angular2应用程序具有十分重要的意义,通常来讲,组件之间 ...
- angularjs组件间通讯_详解Angular2组件之间如何通信
组件之间的共享可以有好几种方式 父->子 input 方式 import {Component,Input} from 'angular2/core'; @Component({ selecto ...
- angular2 组件交互
1. 组件通信 我们知道Angular2应用程序实际上是有很多父子组价组成的组件树,因此,了解组件之间如何通信,特别是父子组件之间,对编写Angular2应用程序具有十分重要的意义,通常来讲,组件之间 ...
- Angular2组件与指令的小实践——实现一个图片轮播组件
如果说模块系统是Angular2的灵魂,那其组件体系就是其躯体,在模块的支持下渲染出所有用户直接看得见的东西,一个项目最表层的东西就是组件呈现的视图. 而除了直接看的见的躯体之外,一个完整的" ...
- angular2组件通讯
父->子 input 方式 import {Component,Input} from 'angular2/core'; @Component({ selector: 'child', temp ...
- Angular2组件开发—模板的逻辑控制(一)
使用条件逻辑 有时我们需要模板的一部分内容在满足一定条件时才显示,比如右边示例中的EzReader组件, 对于试用用户,它将在正文之上额外显示一个广告: 这是指令NgIf发挥作用的场景,它评估属性ng ...
- angular2 组件之间通讯-使用服务通讯模式 2016.10.27 基于正式版ng2
工作中用到ng2的组件通讯 奈何官方文档言简意赅 没说明白 自己搞明白后 整理后分享下 rxjs 不懂的看这篇文章 讲很详细 http://www.open-open.com/lib/view/ope ...
- Angular2 组件与模板 -- 输入和输出属性
Input and Output properties 输入属性是一个带有@Input 装饰器的可设置属性,当它通过属性绑定的形式被绑定时,值会"流入"到这个属性. 输出属性是一个 ...
- Angular2组件与Echarts饼状图交互之饼图制作
一.前言 1.基于ng4项目 2.组件包括:根组件app和饼状图组件echart 二.饼状图开发过程 1.添加插件 echart cnpm install echarts --save 2.创建组件 ...
最新文章
- 那个大战AlphaGo的柯洁,将免试入读清华大学工商管理专业
- dell support
- 一个游戏大量合服代表什么_[游戏服务器从入门到关门]4.分区分服、连服、合服...
- 【Pytorch神经网络理论篇】 05 Module类的使用方法+参数Parameters类+定义训练模型的步骤与方法
- HOG特征(Histogram of Gradient)总结
- cortex M0 典型os模型
- python基础之-数据类型
- 今年因为疫情很多信用卡逾期,结果会怎么样?
- [论文阅读] Unsupervised Domain Adaptive Salient Object Detection Through Uncertainty-Aware Pseudo-Label
- vs2017激活密钥
- 有限单元法matlab编程,有限单元法基础及MATLAB编程-(第3版)
- chrome清除缓存快捷键
- 2021-08-11BUU-CTF:[WUSTCTF2020]alison_likes_jojo
- MSSQL_8 操作结果集
- 企业信息化投入中咨询服务_咨询服务企业如何实施项目核算信息化建设
- 150行Python代码模拟太阳系行星运转
- 看完就明白/dev/sda、/dev/hda是什么了
- MongoDB 拆联查询
- 如何在x86架构下进行ARM镜像的构建与运行
- 小小军团获取服务器配置文件,小小军团2资源获得途径大全_宝石军团币荣誉币高级精华获取方法途径一览_3DM手游...
热门文章
- div包video在某些电脑或者浏览器上出现黑边
- UEFI无法进入WIN10的系统?BIOS找不到ssd硬盘?reboot and select proper boot device的另一种解决思路
- ART笔记1:模糊自适应共振理论
- 正在读《密码王朝》,却忍不住先说两句
- Win10 Rational Rose 安装教程
- 分享 70 个你可能会用到的正则表达式
- 拉格朗日中值+柯西中值求极限+对于等价无穷小,等价代换,极限的四则运算法则是根本+一元微积分
- 这样设置过渡动画,让你的Android手机变得更丝滑
- 全网疯传!Java利用TCP协议实现客户端与服务器通信【附通信源码
- animation 只触发一次的解决办法