Angular 2: @Directive() 指令创建无限滚动 已翻译 100%

oschina 投递于 2016/02/09 22:35 (共 6 段, 翻译完成于 06-22)
阅读 10657
收藏 18
2
加载中

在最近的文章中,我使用 angular 2中新的"ng-repeat"也就是"NgFor"结合通用组件创建(自己的)组件。在这篇文章里,我将继续展示,结合 Angular 2进一步开发的 Echoes Player项目。这次为了更加动态化的展示我们将添加一个无限滚动指令。在Angular 2中无限滚动作为一个属性指令。

Angular 1.x 无限滚动

在当前的Echoes Player生产版本中,为了在滚动的同时添加更多的视频,我使用 "ng-infinite-scroll"。在创建无限滚动方面它是一个非常好的、极简的,指示性的api,并且它在Echoes Player中使用非常简单。如下所示:

<div class="view-content youtube-results youtube-videos" 
infinite-scroll="youtubeVideos.searchMore()" 
infinite-scroll-distance="2"
>
....
</div>

作为一个api它有很多属性来完成无限滚动指令,但是,这次我并不使用它。

在这次投递时,我没有找到任何 angular 2的无限滚动条指令/组件。因此我认为这是一个好机会将angular 1.x中的 "ng-infinite-scroll" 指令迁移到angular 2中,并在迁移的过程中学习如何创建一个无限滚动条指令。请注意 angular 1.x的无限滚动条的源码由"coffeescript"编写。但是生产商最终准备按照ES5编译代码。

温安适
翻译于 2016/06/04 23:29
1

将源代码转换回JavaScript (用这个 http://js2.coffee/), 我开始隔离代码理解它并能够迁移到类ES2015 。

最重要的逻辑被编写为一个angular 1.x控制器. 我想这段代码应该是类ES2015。实际上,我想要迁移的逻辑控制器到类ES2015上,这将无关任何框架或库, 能够在任何地方使用它 ——主要应用于相同的 ponyfoo's dragula 和其他极好的组件.

但首先,我必须了解angular 2 指令的概念。

osc_187988
翻译于 2016/03/31 08:58
2

Angular 2 指令概述

在Angular 2中,除了控件我们还可以使用指令。Angular 2有许多内置的标签可以使用,例如:NgFor,NgIf,NgModel,NgClass。除此之外,还可以使用创建自定义指令的API。

本质上来说,一个指令就像是一个组件。

一共有3种类型的指令:

    1. 组件 - 使用@Component()

    2. 结构化指令 -使用@Directive() - 通常会改变一个元素的DOM - 例如NgIf

    3. 属性指令 -使用@Directive() - 不会改变DOM,但是会添加额外的行为

无限滚动条非常适合使用属性指令 - 它添加了一个滚动事件(行为)到一个元素并且在此元素上执行滚动。

接下来我们使用Angular 2来封装这个指令。

首先,导入相关的依赖

import { Directive, ElementRef, Input, Output, EventEmitter } from 'angular2/core';
import { Scroller } from './scroller';

逻辑和从Angular 1.x中移植的代码会从“scroller.ts”文件引入。

我们将会使用Angular 2的核心对象来定义相关的属性。

g
翻译于 2016/05/04 23:39
1

定义指令

为了声明一个属性指令,类似组件,我们使用“@Directive()”装饰器,在此基础上指定一个属性类选择器(即CSS选择器),示例如下:

@Directive({
  selector: '[infinite-scroll]'
})

指令绑定事件

接下来,我们将为这个指令定义一个类作为控制器,我们希望从元素获取一个输入数据和绑定的事件,因此这个指令将按如下方式对外开放。

export class InfiniteScroll {
  @Input() set infiniteScrollDistance(distance: Number) {
    this._distance = distance;
  }

  @Output() scroll = new EventEmitter();

//...
}

这个"infiniteScrollDistance" 属性被期望从指令的外部进行设置,它将作为这个指令的一个属性API。同样地“scroll”事件将触发一个从外部绑定的方法。综合上述设定,我们将以如下方式使用这个指令:

<div class="search-results"
    infinite-scroll
    [infiniteScrollDistance]="2"
    (scroll)="onScroll()">
</div>

注意上面“div”元素中每个属性是如何匹配指令中的响应声明的。

温安适
翻译于 2016/06/09 16:55
1

在Angular 2中引用指令元素

在angular 1.x的DI(依赖注入)系统中,允许我们使用 "$element" 来获取引用的DOM指令元素:

controller: function ($element) {
$element.on('scroll', onScroll);
}

在angular 2中,我们使用 "ElementRef" 类型定义。使用 Typescript的前提下,我们将能引用“this”上线文访问绑定的DOM指令元素的属性。

constructor(private element: ElementRef) {
   // now, we can reference to: this.element
}

使用ngOnInit来挂钩滚动事件到指令元素 

现在,我们将使用 angular 2的钩子 — "ngOnInit" — 当指令元素已经准备就绪,钩子将运行并且一次性的初始化一个滚动器.注意我在onScroll函数上绑定"this"元素,这能保证当前滚动事件激活事件被触发者的属性时,(本文是)滚动(属性),我们能引用当前DOM指令元素的上下文。

ngOnInit() {
    this.scroller = new Scroller(window, setInterval, this.element, this.onScroll.bind(this), this._distance, {});
  }

  private scroller: Scroller;

  private _distance: Number;

  onScroll() {
    this.scroll.next({});
  }
温安适
翻译于 2016/06/19 09:55
1

滚动器逻辑迁移

     “scroller.ts”就是一个ES2015的类实现。它的大部分实现是从angular1.x的“ng-infinite-scroll”中迁移过来的,它的语法符合ES2015语法规范,并尽力实现了相关更新。

结语

    尽管无限滚动和原angular1.x版本中的许多特性都没有直接实现,但是,angular2中也提供了一些代替的方法,如:angular2中获取实际DOM元素的特殊法“this.$elementRef.nativeElement”。

    ng2开发的Echoes Player是一个开源项目。你很容易获取它的源码,同时,你也可以fork一份ES2015规范的angular1版本的Echoes,自己完成这个项目从ES5向ES2015的迁移。

    echoes-ng2旨在以angular2的更多特性完成整个项目的代码迁移。


乔康007
翻译于 2016/06/22 10:03
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(4)

boystudio
boystudio

引用来自“boystudio”的评论

我最讨厌网页无限滚动,每次想看footer的信息,TMD的一直滚啊滚啊滚啊,就是看不到。

引用来自“狂飙的小蜗牛”的评论

Ctrl+U 直接查看源代码吧。。
Ctrl+U不起作用啊 // (MBP用户)
狂飙的小蜗牛
狂飙的小蜗牛

引用来自“boystudio”的评论

我最讨厌网页无限滚动,每次想看footer的信息,TMD的一直滚啊滚啊滚啊,就是看不到。
Ctrl+U 直接查看源代码吧。。
boystudio
boystudio
我最讨厌网页无限滚动,每次想看footer的信息,TMD的一直滚啊滚啊滚啊,就是看不到。
不得瑟掉毛
不得瑟掉毛
没vue好玩
返回顶部
顶部