15

我正在尝试创建一个指令,以允许用户按部分使用箭头键导航页面。但我也希望能够将这些部分分散在 dom 周围,并且在添加和删除内容时不会中断。我可以想到几种方法来做到这一点,但没有一个是令人满意的:

  • 使用控制器创建一个指令,让其他指令自己注册(并在 $destroy 上取消注册)。但是如果我稍后在中间添加一些东西,这将是不正常的。另外,我试过用这种方式编写它,它的代码似乎比必要的要多。

  • 每当用户点击箭头键时,创建一个空数组,并 $broadcast 一个事件,并带有回调指令以在该列表中注册自己。然后,一旦该列表已满,就前进或后退。他们(应该?)按照他们在 DOM 上的顺序返回,但我不确定,因为这种方式看起来很疯狂和 hackish。

  • 用 css 标记“可选项”的东西,并在 jquery 中以简单的方式编写,如下所示:在新的点击事件上,var all = $('.tabbable')然后用它做显而易见的事情。但我真的不想那样做,因为它不是“角度”的方式。不是出于某种纯粹的感觉,而是因为我将其构建为更大的小部件库的一部分,并且我希望他们可以访问此功能。

那么,有没有什么方法可以让我获得某种类型的所有指令的范围,而无需求助于奇怪的黑客,或将逻辑散布到各处?

4

2 回答 2

5

这是一个很好的问题。+1

首先,按类型查找所有指令或节点违背了 Angular 的方式。View 是 AngularJS 中的官方记录,所以指令应该说他们做什么,做他们说什么。在某处编写一些流程来扫描 DOM 节点并采取相应措施是有问题的,原因有很多,其中最重要的是关注点分离和可测试性。

我很高兴看到您正在考虑其他选项,但我同意您提供的其他选项由于您提到的原因而不是最佳选择。但我还有一个。这是我在另一个应用程序中使用过的,但需要了解分散的 DOM 节点。

首先,我们创建一个服务来管理这个组件的状态。这很简单。让我们称之为SectionsService。接下来,我们创建一个指令来注册部分。为简单起见,我们称之为section。该指令在其链接阶段section向 DOM 节点的 ID(可能以编程方式创建以确保唯一性)注册。SectionsService由于 DOM (大部分)是按顺序处理的,因此添加到 DOM 的节点SectionsService也将按顺序处理。所以 DOM 看起来像这样(省略了无关的东西):

<div section>...</div>

<!-- other stuff -->

<div section>...</div>

<!-- other stuff -->

<!-- etc. -->

(虽然超出了这里的范围,但以一种顺序无关紧要的方式对其进行编程并不是很困难,但它会基于我不知道的你的应用程序的细节。)

接下来,您将创建触发器,例如箭头键处理程序。在这些事件中,您只需告诉SectionService转到列表中的上一个/下一个节点。AngularJS 带有一个名为的服务$anchorScroll,可以用来模拟我们熟悉的浏览器基于哈希的定位。如果您愿意,您显然也可以使用 jQuery 插件来为滚动设置动画。

就是这样!一个非常简单的指令,一个相当简单的服务,以及您需要的任何触发器。总而言之,我猜不到 100 行代码,包括测试。所有组件都是解耦的并且易于测试,但仍然非常简单。观点仍然是真理。Angular 方式被保留。

有很多的欣喜。


我希望这能为您指明正确的方向,但当然可以随时提出后续问题。如果您愿意,我们也可以讨论代码细节;正如我所说,它们不会很复杂。

于 2013-04-04T04:59:45.787 回答
2

AngularJS 服务是单例的,可以通过依赖注入来获取。您可以让您的指令需要状态管理器服务并调用增量器/减量器。

或者,更简单但更脆弱的是,您可以在 $rootScope 中保留一个数组。它比 jquery 选择器全局更惯用的“角度”(但不是很多),但如果您正在构建一个小部件库,它可能不是最佳路线。

于 2013-04-04T04:57:15.967 回答