Angular2.0-组件

截止到目前为止,Angular2.0完成了其alpha-32版本的开发,新的版本还在迭代开发当中,这其中有个问题,就是每个版本相比于以前的版本都会有一些改动,包括API方面的修改,这会导致很多基于以前版本写的demo都无法运行,而且其官网上给出的教程也是基于之前的版本而没有及时更改,这就造成了即使按照官网的教程去编写运行也可能得到不预期的结果,针对这种情况,本文采用最新的较稳定的Angular alpha-31版本重构其官网上的step by step guide,并以此为基点,介绍Angular2中的组件(components).

组件(Components)是在软件开发过程中的一种发展趋势,它基于封装技术,着力于减少软件模块开发中的耦合度,在传统的后端语言开发中早已经得到了很好的实现和发展,比如微软的com组件。在web开发中,截止到目前为止,还没有一种能够得到浏览器原生支持并且广泛使用的组件技术。目前W3C制定出了web components规范,Shadow DOM作为实现该规范的一种关键技术也是在不断的发展中。可惜的是目前浏览器支持度并不好,离实际广泛使用还存在很长的一段距离。所以在目前比较著名的解决方案是谷歌的polymer和Mozilla的X-TAG,它们允许在一部分现代浏览器上能够封装自定义用户组件,并且让该组件独立于客户端js之外,即不能够通过客户端js去修改或者操作该组件内部元素,自定义组件对外表现为一个整体。这就好比html5的video 标签,你只需要在页面上放置一个video标签,它就能够被浏览器渲染成一个播放的画面以及播放控制条,即使你在开发者工具中查看原码,也能够看到一个video标签而不能够看到它内部的实现。外部js只能够通过有限的API去控制它的行为,而且不管该页面本来样式有何不同,它在不同页面上渲染出来的效果都是相同的。这就是web 组件化。

Angular2.0也正是按照这一思路来设计整个框架的,可以说Angular2.0中,组件是它的核心概念。前面讲到,由于浏览器目前还不能够提供对web Components的原生支持,所以Angular从框架的角度来视图解决这一问题。本文的目的就是讲解如何在Angular2.0中实现一个组件。

为了便于快速演示效果,免去环境搭建的过程,我在github上传了一个种子项目,用于以后对Angular2.0的学习。本文基于这个项目,一步步去了解组件的概念。

步骤一,克隆种子项目到本地

在本地创建一个文件夹,在该文件夹中进行git clone操作

git clone https://github.com/myzhibie/ng2-demo.git

第二步,本地全局安装gulp(如果已经安装,可以省去这一步)

npm install -g gulp

第三步,在项目根目录下安装项目的所有依赖项

npm install

这一步可能需要FQ,如果失败一般都是网络原因。

如果上述步骤都成功,那么到此为止,已经可以运行该种子项目了

gulp play

在原始的种子项目中,src文件夹下已经有了本文的所有代码作为参考,可以将它们完全(除了index.html和style.css)删除然后自己创建。

1.创建一个简单的组件

在src文件夹下创建一个display.js文件(严格来讲是ts文件,因为本文是采用typescript脚本来构架的,当然你也可以使用ES5,ES6来编写整个项目,但是相比于typescript较为复杂,Angular2官方的教程中,也是采用首选typescript脚本,目测随着Angular2的推动,微软的typescript会火啊),用来编写组件的逻辑,并在html中采用如下代码引用它

System.import(‘display‘);

在index.html中,添加一行html代码

<display></display>

这表示自定义了一个display组件。

然后转到display.js中,编写逻辑如下

 1 import {ComponentAnnotation as Component, ViewAnnotation as View, bootstrap,NgFor,NgIf} from ‘angular2/angular2‘;
 2
 3 class FriendService {
 4     names:Array<string>;
 5     constructor(){
 6         this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
 7     }
 8 }
 9 @Component({
10     selector: ‘display‘,
11     hostInjector:[ FriendService ]
12 })
13 @View({
14     templateUrl: ‘showData.html‘,
15     directives:[NgFor,NgIf]
16 })
17  class DisplayComponent {
18     myName: string;
19     names:Array<string>;
20     constructor(friendService:FriendService) {
21         this.myName=‘myzhibie‘;
22         this.names=friendService.names;
23     }
24     updateItems(name:string){
25        this.names.push(name);
26     }
27     doneTyping($event){
28         if($event.which===13){
29             this.updateItems($event.target.value);
30             $event.target.value=null;
31         }
32     }
33 }
34
35 bootstrap(DisplayComponent);

代码第一行首先引入了component,view,bootstrap,以及ngFor,ngIf几个核心的指令,第3到8行定义了一个外部的service,类似于Angular1.X中的service,可以将一些公用的方法或者代码抽象为一个service,然后采用注入的方式在Component中进行调用,从思想上来讲,这和Angular1.X没有任何区别,但是具体的定义方式发生了较大变化,Angular2中就是使用class关键字来定义,结构很清晰。这个service拥有一个names属性是字符串数组类型,并在构造函数中对它进行了初始化。代码9到12行定义了该组件相关的配置项,selector属性是一个选择器,用于选择该组件对应于html页面上的哪个DOM元素。hostInjector属性表示将FriendService注入到了这个组件当中,这行代码是保证能够在Angular2 alpha31版本运行的依赖注入的方式,官网上给出的是appInjector,那个是之前的版本的DI的配置属性。

代码13-16行定义了该组件view相关的配置,templateUrl代表其对应的模板文件,是showData.html.directives表示在其模板中可以使用的内置指令,这里我们选择ngFor和ngIf,前者用来循环,后者用来进行判断,具体用法在showData.html中会给出。

代码第17到33行就是定义了一个完整的组件,你会发现就是一个class,而不是Angular1.X中那种controller的形式,实际上,这个组件的class就是它的Controller,这种定义方式更优雅简洁一些。20-23行是这个组件的构造函数,用来初始化它的属性,其中names属性是通过依赖注入的friendService对象来的。同时在该controller种定义了两个方法,updateItems用来添加新的names项,doneTyping方法用来处理组件中的input标签在完成输入后按回车键去添加names项的操作。下面是showData.html的内容

1 <p>friends:</p>
2         <ul>
3             <li *ng-for="#name of names">
4                 {{ name }}
5             </li>
6         </ul>
7         <input #nametext (keyup)="doneTyping($event)">
8         <button  (click)="updateItems(nametext.value)" >addItems</button>
9         <p class="p2" *ng-if="names.length > 3">you have many friends</p>

第3到6行是一个ul里面加入了li,通过ng-for指令循环(类似于1中的ng-repeat)其controller中的names属性,注意调用指令的时候前面要加上*表示这是一个Angular2的内置指令,同时使用#来定义在循环中的一个局部变量,第4行使用{{}}来绑定变量。第7行是一个input 标签,该标签中定义了一个nametext局部变量,可以在该页面的其他地方引用。需要注意的是,你不能定义成nameText或者name-text,这两种方式在Angular2中会被转化,得不到确定的结果,相信这个问题在随后的正式发布中会得到解决。同时,给input标签注册一个onkeyup事件,让它指向其controller中的doneTyping方法,并且它的参数$event代表event对象。第8行给button标签注册一个onclick事件,它的参数通过局部变量nametext来引用上面input标签的值。第9行在p标签中采用ng-if指定,如果其controller的names长度大于3就显示这个p标签,否则不显示。

运行以上代码,结果如下:

可以通过在input中写入值点击按钮添加li,也可以通过回车键添加。

2.组件之间的引用

通过上面的练习,我们知道了如何定义一个组件并为它绑定事件来响应用户请求,实际上就是定义一个完整的组件,但是web引用并不是一个组件就能够搞定的,Angular2.0允许你以更简单的方式在自定义组件中引用其他组件,也就是组件之间的引用。

首先的index.html中添加一行代码

<parent></parent>

表示这是一个parent组件,然后添加一个parent.js文件,编写逻辑如下:

 1 import {ComponentAnnotation as Component, ViewAnnotation as View, bootstrap,NgFor,NgIf} from ‘angular2/angular2‘;
 2
 3 @Component({
 4     selector:‘parent‘
 5 })
 6
 7 @View({
 8     template:‘<h1 class="hparent">{{message}}</h1><child></child>‘,
 9     directives:[ChildComponent]
10 })
11 class ParentComponent {
12     message:string;
13     constructor(){
14         this.message=‘parent component‘;
15     }
16 }
17
18 @Component ({
19     selector:‘child‘
20 })
21
22 @View({
23     template:‘<p class="pchild">{{ message }}</p>‘
24 })
25
26 class ChildComponent{
27     message:string;
28     constructor(){
29         this.message=‘child component‘;
30     }
31 }
32 bootstrap(ParentComponent);

代码第3到16行用于定义父组件,第18到31行定义了一个子组件ChildComponent,需要注意的是第8-9行,组件之间的引用是在view注解中template中插入组件的占位符<child></child>,然后在directives中引用它的class名称。这就完成了组件的调用,通过这种方式,可以采用“堆积木”的方法来构建我们的web应用,同时它提高了代码的复用率。运行结果如下:

审查元素结果如下:

从上面可以看出,Angular2.0对于组件的定义和使用相对于Angular1.x是更为简单和优雅的,学习曲线较Angular1.X平坦一些。

原码地址https://github.com/myzhibie/ng2-demo

时间: 2024-08-28 08:09:39

Angular2.0-组件的相关文章

angular2.0学习笔记1.开发环境搭建

开发环境, 1.安装Node.js®和npm, node 6.9.x 和 npm 3.x.x 以上的版本. 更老的版本可能会出现错误,更新的版本则没问题. 控制台窗口中运行命令 node -v 和 npm -v,来查看版本 2. 运行 npm config set registry https://registry.npm.taobao.org 因为国内访问http://npmjs.org(angular2.0组件库) 的站点访问经常不是很顺畅,所以换成淘宝的镜像, 3. 然后全局安装 Angu

Angular2.0开发-WebStorm配置及第一个Hello World(一)

公司项目开发用到angular2.0+webpai,特此记录学习开发笔记. WebStorm是Angular2.0开发的不二选择,下面将逐步介绍WebStorm的安装配置及使用示例.  1.下载最新版本WebStorm:WebStorm下载 2.创建一个Angular项目 Angular CLI 可以看到图片上有两个关于Angular的选择.一个是AngularJS,这个创建的是基于Angular1.0版本类的project.另一个Angular CLI创建的才是基于Angular2.0的项目.

Angular2.0视频教程来了!

各位道友大家好: "Angular2.0视频教程"来了!这是全球第一个完整的Angular 2.0系列视频教程,到目前为止也是唯一的,该系列的视频在优酷和youtube同步播出. 还是大漠穷秋老师,还是熟悉的声音,还是淡淡的小幽默.3年前,大漠老师在慕课网发布了"AngularJS实战" http://www.imooc.com/learn/156 系列视频教程,迄今为止已经有14万人学习,整体评分9.6分.很多道友反馈说,通过学习这门课程找到了心仪的工作,大漠老师

通信vue2.0组件

vue2.0组件通信各种情况总结与实例分析 Props在vue组件中各种角色总结 在Vue中组件是实现模块化开发的主要内容,而组件的通信更是vue数据驱动的灵魂,现就四种主要情况总结如下: 使用props传递数据---组件内部 //html <div id="app1"> <i>注意命名规定:仅在html内使用my-message</i> <child my-message="组件内部数据传递"></child&

Angular2.0 Form

对于Angular2.0 的Form表单中的隐藏和验证,个人觉得还是挺有意思的. 1.通过ngModel 跟踪修改状态与验证. 在表单中使用 ngModel 可以获得更多的控制权,包括一些常用的验证. ngModel 不仅仅可以跟踪状态(表单中各个控件的状态)还可以用特定的Angular CSS 类来更新控件,以表达当前的状态 (如显示和隐藏) ng-touched:控件已被访问过的css 类: ng-untouched 为没有被访问过的CSS 类 ng-dirty :控件值已经发生变化,ng-

Vue2.0组件间数据传递

Vue1.0组件间传递 使用$on()监听事件: 使用$emit()在它上面触发事件: 使用$dispatch()派发事件,事件沿着父链冒泡: 使用$broadcast()广播事件,事件向下传导给所有的后代 Vue2.0后$dispatch(),$broadcast()被弃用,见https://cn.vuejs.org/v2/guide/migration.html#dispatch-和-broadcast-替换 1,父组件向子组件传递场景:Father上一个输入框,根据输入传递到Child组件

IIS6缺少ASP.NET v2.0组件

服务器上安装了ASP.NET v2.0组件,但是在IIS的Web服务扩展中并没有找到ASP.NET v2.050727这项,这导致基于.NET2.0开发的网页都无法正常浏览. 解决方法:打开IIS,转至Web服务扩展中,点击右侧窗口任务下的“添加一个新的Web服务扩展”,在弹出的窗口中,点击添加,然后找到x:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll(x为系统安装盘符,一般为C),再点击确定按钮保存设置,最后再设置其状

vue2.0组件之间的传值--新入坑,请指教

prop down   emit up 嘿嘿    如果是第一次接触vue2.0组件传值的肯定很疑惑,这是什么意思(大神总结的,我也就是拿来用用) "down"->指的是下的意思,即父组件向子组件传值,用props:"up"->指的是上的意思,即子组件想父组件传值,用emit. 1.子组件向父组件的传值: Child.vue <template> <div class="child"> <h1>子组

Vue2.0组件注册

//全局注册: Vue.component("my-component",{ template:'<div>A custom component!</div>' }); /*交换位置会报错----创建组件必须在根实例化之前*/ //创建根实例: new Vue({ el:"#app" }) --------- //局部注册: new Vue({ el: "#app1", components: { // <my-zu

vue-router2.0 组件之间传参及获取动态参数

<li v-for=" el in hotLins" > <router-link :to="{path:'details',query: {id:el.tog_line_id}}"> <img :src="el.image_list[0]"> <h3>{{el.tourism_name}} {{el.tog_line_id}}</h3> <p>{{el.address}}&