• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Angular2利用组件与指令实现图片轮播组件

angularjs 搞代码 4年前 (2021-12-31) 15次浏览 已收录 0个评论

这篇文章主要给大家介绍了Angular2中组件与指令的一个小实践,利用组件和指令实现一个图片轮播组件的相关资料,文中给出了详细的介绍和示例代码,需要的朋友可以参考学习,下面来一起看看吧。

前言

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

而除了直接看的见的躯体之外,一个完整的“生物”还需要有感觉器官,用来感知外界与其的交互,这就是指令要做的事情。
本文将使用Angular2提供的强大的组件与指令等功能制作出一个简单的图片轮播控件,继续上文打的比方的话这就像是一个“器官”,功能是呈现图片,并感知用户的点击或手势来切换图片。

一、创建组件

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

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

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

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

 @Component({ selector: 'my-slide-img', templateUrl: 'slide-img.component.html', styleUrls: ['slide-img.component.css'], animations: [ trigger('imgMove', [ /** 不显示 */ state('off', style({'display': 'none', 'z-index': '0', 'transform': 'translateX(0)'})), /** 上一张图片 */ state('prev', style({'z-index': '1', 'transform': 'translateX(-100%)'})), /** 下一张图片 */ state('next', style({'z-index': '2', 'transform': 'translateX(100%)'})), /** 当前图片 */ state('on', style({'z-index': '3', 'transform': 'translateX(0)'})), transition('prev=>on', [ animate('0.3s ease-in') ]), transition('next=>on', [ animate('0.3s ease-in') ]), transition('on=>prev', [ animate('0.3s ease-in') ]), transition('on=>next', [ animate('0.3s ease-in') ]) ]) ] }) export class SlideImgComponent { }

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

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

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

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

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

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

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

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

二、实现组件

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

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

 @Input() public imgs: SlideImg[];

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

 

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

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

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

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

 <div class="imgs"> </div><div class="btn">Prev</div><div class="btn">Next</div>
 .imgs{ position: relative;width: 100%;height: 15em; overflow: hidden; } .img{ position: absolute; width: 100%; height: 100%; background: pink; transition: 0.2s; } .btn{ display: inline-block; padding: 1em 2em;font-size: 1em;border-radius: 0.5em; border: 1px solid #ddd;cursor: pointer; margin: 1em;background: #eee;box-shadow: 0.1em 0.1em 0.2em #aaa; } .btn:active{ background: #eee; box-shadow: none; }
 import { Component, OnInit, Input, animate, style, transition, trigger, state, HostListener } from '@angular/core'; import { SlideImg } from './slide-img.interface'; @Component({ selector: 'my-slide-img', templateUrl: 'slide-img.component.html', styleUrls: ['slide-img.component.css'], animations: [ trigger('imgMove', [ /** 不显示 */ state('off', style({'display': 'none', 'z-index': '0', 'transform': 'translateX(0)'})), /** 上一张图片 */ state('prev', style({'z-index': '1', 'transform': 'translateX(-100%)'})), /** 下一张图片 */ state('next', style({'z-index': '2', 'transform': 'translateX(100%)'})), /** 当前图片 */ state('on', style({'z-index': '3', 'transform': 'translateX(0)'})), transition('prev=>on', [ animate('0.3s ease-in') ]), transition('next=>on', [ animate('0.3s ease-in') ]), transition('on=>prev', [ animate('0.3s ease-in') ]), transition('on=>next', [ animate('0.3s ease-in') ]) ]) ] }) export class SlideImgComponent { @Input() public imgs: SlideImg[]; public current; constructor() { this.current = 0; } public ImgState(index) { if (this.imgs && this.imgs.length) { if (this.current === 0) { return index<span style="color:transparent">来源gaodai#ma#com搞*!代#%^码网</span> === 0 ? 'on' : index === 1 ? 'next' : index === this.imgs.length - 1 ? 'prev' : 'off'; } else if (this.current === this.imgs.length - 1) { return index === this.imgs.length - 1 ? 'on' : index === this.imgs.length - 2 ? 'prev' : index === 0 ? 'next' : 'off'; } switch (index - this.current) { case 0: return 'on'; case 1: return 'next'; case -1: return 'prev'; default: return 'off'; } } else { return 'off'; } } public Next() { this.current = (this.current + 1) % this.imgs.length; } public Prev() { this.current = this.current - 1 <0 ? this.imgs.length - 1 : this.current 1; } public change(e) { if (e=== 'left') this.next(); else 'right') this.prev(); }<pre></div><p>其中有两个地方为讲到,一个是组件代码引入了一个<span style="color: #3366ff">slide-img.interface </span>模块,这个仅仅用来规范一下轮播图片的格式,二是在html中还有一个节点名为(<span style="color: #3366ff">mySwipe</span>)这就是接下来要讲的输出属性,目前知道的它的作用是,当用户滑动图片时,将触发此节点配置的回调方法,所做的事情就是判断发生了左滑事件还是右滑事件,分别触发上一张图或下一张图的切换。</p><p><span style="color: #ff0000"><strong>三、给轮播图片控件加上手势效果</strong></span></p><p>轮播图片在移动端很需要加上手势滑动的效果,所以接下来要给这个轮播组件加上一个指令,用于响应用户的滑动手势。代码如下:</p><div class="gaodaimacode"><pre class="prettyprint linenums"> import { Directive, Input, HostListener, Output, EventEmitter } from '@angular/core'; @Directive({ selector: '[mySwipe]' }) export class SwipeDirective { @Output() public mySwipe = new EventEmitter(); private touchStartX; private touchStartY; @HostListener('touchstart', ['$event']) public onTouchStart(e) { this.touchStartX = e.changedTouches[0].clientX; this.touchStartY = e.changedTouches[0].clientY; } @HostListener('touchend', ['$event']) public onTouchEnd(e) { let moveX = e.changedTouches[0].clientX - this.touchStartX; let moveY = e.changedTouches[0].clientY - this.touchStartY; if (Math.abs(moveY)  50) { this.mySwipe.emit('right'); } else if (moveX  Math.abs(moveX)) { /** * Y轴移动大于X轴 判定为纵向滑动 */ if (moveY > 50) { this.mySwipe.emit('down'); } else if (moveY <-50) { this.mySwipe.emit('up'); } } this.touchStartX = this.touchStartY = -1; } }

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

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

 @Output() public mySwipe = new EventEmitter();

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

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

总结以及题外话:

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

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

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

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

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

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

以上就是Angular2利用组件与指令实现图片轮播组件的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Angular2利用组件与指令实现图片轮播组件

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址