在Angular

时间:2016-08-01 14:10:32

标签: angularjs angularjs-directive

我有一个下拉列表元素指令,实质上是一个带有附加功能的样式化下拉列表。

我的下拉控制器有一个名为openDropdownItems的功能,可以在显示列表时执行。

然后我还有另一个名为setInViewWhen属性指令,它在条件为真时将元素滚动到视图中时提供表达式。

<x set-in-view-when="something.item === selectedItem">

这只是一些应用了我的属性指令的 X 元素的示例。

问题是我希望我的下拉列表项(LI即)具有此指令,因此当用户使用键盘在其上导航时,它会在通过可见视口时自动滚动它们。这些项目是在可滚动容器中显示还是作为整体显示在比浏览器视口更长的列表中并不是真正相关的。

主要思想是滚动以跟随下拉列表选择。是否应滚动主窗口。

问题

我可以使我的setInViewWhen指令完全独立,但这意味着每当条件发生变化时我都必须搜索最近的可滚动容器。这似乎是我想避免重复的相当多的处理(我需要向上遍历DOM,检查每个节点的计算样式表属性OverflowY +一些额外的检查。

这基本上似乎是多余的,因为每当我得到最接近的滚动祖先时,所有具有相同指令的兄弟元素都可以重用计算结果。

问题1

如何在兄弟指令之间分享这些知识?如果我要发射一个事件,我不知道接收者是否是兄弟姐妹,没有任何额外的处理。

问题2

每次当我的指令条件成立时,我都不会检查可滚动容器,理论上我可以更改下拉父级openDropdownItems以首先完成它的原始执行,然后执行可滚动性检查并使用它的结果以及我的指令条件。 我可以通过指令requires属性访问我的指令中的下拉控制器,并在后链接阶段进行调整。

但这也意味着我无法在dropdown之外使用我的指令,因为它是一个通常可用的指令,我可以附加在我的应用程序中的几个元素上,以便在某些条件下将元素滚动到视图中。

你会建议怎么做?

1 个答案:

答案 0 :(得分:0)

总结评论:

  • 对于问题1,兄弟指令没有直接相互通信的方式。我通常创建一个包装父指令来中继消息。
  • 根据评论,条件something.item === selectedItem引入了一个手表;对于选择项目的列表,这可能是许多手表并且对性能有害。即使它现在没有发生,它也是一个陷阱,有人可能会被诱使将其用于未来的一长串物品。我希望在<li>的父级中有一个监视,并添加&#34;滚动到视图&#34;那里的逻辑。
  • 考虑到上一点,您仍然可以拥有一个独立的setInViewWhen指令(看起来很有用)并拥有X的控制器 - 选择替换指令共享代码。例如。:
    • 包含常用功能的服务
    • 包含基类(Typescript或JS)的角度值,并且setInViewWhenX指令的控制器都从它延伸
    • 或任何其他方便您案例的解决方案
  • 与问题2相关:孩子们可以要求他们的父母改变其中的方法(这种技术甚至得到Angular的支持,请参阅ng-model和自定义控件,他们通过替换它来覆盖ngModel.$render() 。但是,如果你这样做,会有很多孩子改变父母的方法,这可能会导致混乱。