如果说模块系统是Angular2的灵魂,那其组件体系就是其躯体,在模块的支持下渲染出所有用户直接看得见的东西,一个项目最表层的东西就是组件呈现的视图。
而除了直接看的见的躯体之外,一个完整的“生物”还需要有感觉器官,用来感知外界与其的交互,这就是指令要做的事情。
本文将使用Angular2提供的强大的组件与指令等功能制作出一个简单的图片轮播控件,继续上文打的比方的话这就像是一个“器官”,功能是呈现图片,并感知用户的点击或手势来切换图片。

一、创建组件

结束上文打的尴尬的比方,着眼于一个待开发的ng2项目,它有一个空白的特性页面,现在需要在上面呈现一个图片轮播窗口。

图片轮播是一个需要给用户看见的东西,所以应该使用ng2的组件(Component)来实现它,并且这个功能较为通用,可以将其独立出来方便以后再次使用到。

所以在项目中的共享模块(SharedModule)下创建这个组件名为 slide-img.component

使用ng2提供的组建装饰器来将这个TypeScript模块正式变身成ng2的组件:

 组件的声明

其参数其实已经不能再明确了:

      selector就是其使用时的标签名,

      templateUrl即组件关联的界面的模板,

      styleUrls即仅在此组件内生效的样式表,

      animations定义的是一套ng2动画规则。

      讲讲最后的这个动画规则:

        ng2的动画其实非常简单,步骤为1.定义触发器名,2.定义状态,3.定义切换样式,4.将此触发器应用到具体的标签中,状态作为触发器的值传入。

        当ng2检测到动画状态的值更改了,就会套用定义的切换样式,用法思路还算比较明确(当然实际使用时会有一些尴尬的小问题)


二、实现组件

既然是轮播图片组件,要做的事情首先就得是传入轮播图片然后显示出来。

使用过ng1的朋友一定还记得其在定义指令(angular.directive)的时候是通过scope参数(或者link)来传入数据的,而ng2中使用的是Input装饰器,使用的方法如下:

@Input() public imgs: SlideImg[];

使用了此装饰器的变量imgs将可以在运行时接收其他组件传入的图片列表。使用方法如下:

<my-slide-img [imgs]="imgs"></my-slide-img>

关于这里的方括号“[]”,ng2其实提供了多种方式来进行组件模板中值的传入,其中这种变量名用方括号包起来的方法就是其中之一,代表是输入的值,而后面会见到的圆括号来包围的方式,是代表输出的值。

传入了数据后,下一步就是要如何来显示图片到界面上了,没错就是ng1中ng-for指令的升级版*ngFor,除了写法外表面上的差别不大。

关于轮播图片逻辑的具体实现逻辑,笔者使用的方式就是利用ng2动画的状态切换,设置一个当前图片索引值current,*ngFor渲染的图片将其索引与当前索引比较,如果是相邻的图片则设为'prev'状态与'next'状态,ng2会为其加上位置属性为-100%或者100%,如果是当前图片则设为'on'状态,ng2会将其的位置属性设为0,其余均设为'off'状态,ng2会直接将其隐藏,实现的逻辑很简单,考虑也不算周全,笔者就不继续解释献丑了。

最终的轮播图片组件及其模板文件代码如下:

 slide-img.component.html
 slide-img.component.css
 slide-img.component.ts

其中有两个地方为讲到,一个是组件代码引入了一个slide-img.interface 模块,这个仅仅用来规范一下轮播图片的格式,二是在html中还有一个节点名为(mySwipe)这就是接下来要讲的输出属性,目前知道的它的作用是,当用户滑动图片时,将触发此节点配置的回调方法,所做的事情就是判断发生了左滑事件还是右滑事件,分别触发上一张图或下一张图的切换。

三、给轮播图片控件加上手势效果

轮播图片在移动端很需要加上手势滑动的效果,所以接下来要给这个轮播组件加上一个指令,用于响应用户的滑动手势。代码如下:

 swipe.directive.ts

指令的声明甚至简单过组建的声明,因为指令不需要依赖于某个视图模板,只需要有个指令名称就足够了。

需要关心的是指令中定义的输出属性:

@Output() public mySwipe = new EventEmitter<string>();

此属性接收了上文组件中的Change($event)回调方法,在此指令中,所做的事情就是监听组件的滑动,收到滑动事件后就触发这个回调,监听使用的是ng2的HostListener装饰器,用法显而易见了。

现在运行起项目来看看效果吧(比较懒就不截动图了):

总结以及题外话:

本文主要使用了ng2几个比较基本的功能——输入属性(Input装饰器)、输出属性(Outut装饰器)、HostListener装饰器、几个系统指令(ngFor)、ng2动画实现了一个比较基本的图片轮播控件。

使用好ng2的组件以及指令能完成很多的事情,其需要学习的东西绝不仅限与本文提到的,包括其底层的渲染,也很值得去研究。

最后提一个尴尬的问题点:

其实最初写这个轮播图片的时候想过要加上拖动的,也就是图片会随手势的滑动实时更新位置。

但后来发现ng2的动画有个尴尬的地方,那就是一定会从初始状态按照定义好的转换效果变化到目标状态。实时滑动需要我在滑动过程中就改变图片的位置,这样的话在滑动结束需要切换图片时,图片居然强行回到了初始位置然后才开始转换动画,一时还想不到继续使用ng2动画来实现这种实时滑动的完美解决办法,实在是尴尬。

Angular2组件与指令的小实践的更多相关文章

  1. Angular2组件与指令的小实践——实现一个图片轮播组件

    如果说模块系统是Angular2的灵魂,那其组件体系就是其躯体,在模块的支持下渲染出所有用户直接看得见的东西,一个项目最表层的东西就是组件呈现的视图.而除了直接看的见的躯体之外,一个完整的" ...

  2. 几个小实践带你快速上手MindSpore

    摘要:本文将带大家通过几个小实践快速上手MindSpore,其中包括MindSpore端边云统一格式及华为智慧终端背后的黑科技. MindSpore介绍 MindSpore是一种适用于端边云场景的新型 ...

  3. Angular2 组件

    1. 组件说明 Angular2 组件是构成Angular2应用程序的核心部分,Angualr2应用程序本质上来说就是一个组件树,Angular2组件一般由模块,注解,元数据以及组件类组成,实现组件类 ...

  4. react、react-router、redux 也许是最佳小实践1

    小前言 这是一个小小的有关react的小例子,希望通过一个小例子,可以让新手更好的了解到react.react-router4.0.redux的集中使用方法. 这是基于create-react-app ...

  5. F#之旅4 - 小实践之快排

    参考文章:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/fvsc-quicksort.html F#之旅4 - 小 ...

  6. 百度前端技术学院task35源代码——听指令的小方块3

    任务描述 如图,命令输入框由input变为textarea,可以允许输入多条指令,每一行一条 textarea左侧有一列可以显示当前行数的列(代码行数列),列数保持和textarea中一致 当text ...

  7. 百度前端技术学院task34源码——会指令的小块2

    任务描述 增加新的指令如下: TRA LEF:向屏幕的左侧移动一格,方向不变 TRA TOP:向屏幕的上面移动一格,方向不变 TRA RIG:向屏幕的右侧移动一格,方向不变 TRA BOT:向屏幕的下 ...

  8. 百度前端学院task33源码及总结——听指令的小方块

    任务描述 如图,实现一个类似棋盘的格子空间,每个格子用两个数字可以定位,一个红正方形的DOM在这个空间内,正方形中的蓝色边表示这是他的正面,有一个input输入框 在输入框中允许输入如下指令,按下按钮 ...

  9. 在angular7中创建组件/自定义指令/管道

    在angular7中创建组件/自定义指令/管道 组件 使用命令创建组件 创建组件的命令:ng generate component 组件名 生成的组件组成: 组件名.html .组件名.ts.组件名. ...

随机推荐

  1. django开发总结

    首先我用的是虚拟机,python3.6+django1.11.0: 为了版本的一致,以及在环境种更好的体验,我们需要的是先用虚拟环境virtualenv其命令有: 1.创建环境(name是虚拟环境名字 ...

  2. 说说我和QQ和她的故事

    这篇文章纯属感慨而写, 没有教学性质,额我是Jyang 2780217151是我现在用的QQ,然而这并不是我要说的 大概在11年还是12年的时候,我玩这些所谓的黑客圈子,以前的网名我就不说了. 我记得 ...

  3. 我的acm vim 备忘

    一.從命令到編輯模式 a :当前单词后面插入Appendi :当前位置插入Inserto :当前行下新开一行插入Open new lineA :当前行尾插入AppendI :当前行首插入InsertO ...

  4. 【前端】Github Pages 与域名关联简明教程

    Github Pages 与域名关联简明教程 1. 向你的 Github Pages 仓库添加一个CNAME(一定要*大写*)文件 其中只能包含一个顶级域名,像这样: example.com 如果你是 ...

  5. 谈谈个人网站的建立(二)—— lucene的使用

    首先,帮忙点击一下我的网站http://www.wenzhihuai.com/ .谢谢啊,如果可以,GitHub上麻烦给个star,以后面试能讲讲这个项目,GitHub地址https://github ...

  6. Python学习笔记6

    raw_input 与 input 使用input和raw_input都可以读取控制台的输入,但是input和raw_input在处理数字时是有区别的 当输入为纯数字时 input返回的是数值类型,如 ...

  7. KVM+Qemu+Libvirt实战

    上一篇的文章是为了给这一篇文件提供理论的基础,在这篇文章中我将带大家一起来实现在linux中虚拟出ubuntu的server版来 我们需要用KVM+Qemu+Libvirt来进行kvm全虚拟化,创建虚 ...

  8. 使用javaconfig配置freemarker

    package com.yy.config; import org.springframework.context.annotation.Bean; import org.springframewor ...

  9. 多路复用(select、epoll)实现tcp服务

    -------------------------------多路复用的服务器(select)------------------------------- 网络通信被Unix系统抽象为文件的读写,通 ...

  10. zabbix上监控docker

    说明 第一种方案,借助docker的python版的api,然后通过自己封装自定义脚本来做,稍微麻烦点,但是可以达到个人自定义的效果. 第二种借助国外的一位大神已经封装好的模板来做,简单省事情,不过功 ...