Angular JS指令操纵几个元素

时间:2014-06-02 23:20:32

标签: javascript angularjs

据我所知,每当我们想要在Angular JS中进行DOM操作时,无论出于何种原因(显示数据,控制布局行为等),我们都应该使用指令。现在有时候对一个元素的某些DOM操作需要有关其他DOM元素的信息才能动作。

一个真实世界的例子:假设我们想要调整div的大小以始终适合所有屏幕。所以基本上div有一个定义的高度,我们想根据内容改变这个高度,依此类推使div填满屏幕。通常我们需要在进行这种操作时考虑其他DOM元素,如标题等。

另一个例子如下:假设我们有一个登录表单,在表单底部我们想要一个链接,允许用户在没有帐户的情况下注册。当用户点击按钮时,它应该从登录到注册翻转表单(通常编码和隐藏其他表单)。没关系,如果我们在链接上添加指令来执行此操作,则需要操作表单div,如果我们输入表单div,则需要与链接进行通信。

在这些情况下(我真的很普遍,那只是两种可能的情况),我们应该如何采取行动的一般指导原则?

我的意思是,我们有一些DOM元素<A>,我们想以某种方式操纵它,但为了这样做,我们需要有关另一组DOM元素<A1>,...,{{的信息。 1}},那么我们如何以一致性来处理这个问题呢?

我已经考虑过使用<An>并共享指令控制器。但这很奇怪,再次调整大小调整示例,我们将require作为<div maintain-height>指令,并使用逻辑来调整此div的大小。然后,为了与它进行通信,我们需要放入触发调整大小某些指令的每个其他地方。它看起来并不自然,而在其他情况下我认为感觉是一样的。

所以,当我们遇到这种情况时,我们如何处理它维护一切写得好,可维护,可测试等等?

3 个答案:

答案 0 :(得分:1)

执行此操作的要求可能表示无角度架构。您需要的任何信息都应该在您的视图模型中,可以在当前范围内,也可以在您可以轻松访问的另一个范围内。您可以通过广播(或发送)消息在范围之间进行通信。您还可以将所需的数据放入服务中,并将其注入控制器中的任何位置。

如果由于某种原因你必须访问其他元素并直接从它们读取数据,你可以在指令中以正常的jQuery / jQLite方式执行此操作。还有$ document service。

您描述的特定用例似乎很奇怪。为什么不使用CSS来处理重新调整DOM元素的大小?

您的其他用例(更改表单)将由范围变量(例如showLogin)处理。根据该变量的值隐藏或显示两种不同的形式。或者我错过了一些关于你的要求的东西?

答案 1 :(得分:0)

所有DOM操作应始终始终在AngularJS中的指令中完成。要在指令之间共享非DOM数据,请使用控制器和/或服务。

在您的第一个用例中,我会使用类似Twitter-Bootstrap的内容来执行响应式操作。 Bootstrap是一个CSS框架,虽然它包含JavaScript组件。其中一个CSS组件是调整元素大小以使它们在某些屏幕尺寸上看起来很好。我见过的大多数类屏幕尺寸都有4种尺寸:小屏幕,如智能手机屏幕,平板电脑屏幕,中小型电脑和大型电脑。这些尺寸似乎有效,除了可能直接介于两者之间的尺寸,我认为并没有广泛实施。这些类通常用于容器元素,例如<div> s,尽管还有其他类可以附加到标题等。

至于您的第二个用例,登录始终是一个挑战。我不确定如何解决您的具体情况,因为我不需要使网站非常安全,但我首先要定义一个用于登录控制器的变量,并使用它来决定放置什么登录状态该页面中的变量将使与此登录状态对应的指令可见,其他指令不可见。当用户按下链接时,它将改变该变量,这反过来会改变可见指令。我知道我总是在指令中做DOM的东西,但这是一个边缘情况,并处理范围,这是控制器的权限。

答案 2 :(得分:0)

指令中DOM依赖关系的问题在于DOM可以随着指令的编译和链接而变异和改变。

然而,只要规则遵守规则,您就可以依赖以下几点:

  1. 在编译阶段,通过将DOM树从父级转到子级从最外层元素到最内层元素并按优先级顺序(从最高到最低)调用它们的“编译”函数来编译元素。
  2. 指令的编译功能只应该修改它的子节点(不是它的父节点或祖父母节目)。原因是子元素尚未编译,因此可以安全地改变它们,角度编译器最终会遍历DOM树并编译修改后的DOM。父元素已经“走了”,编译父元素的机会已经过去了。如果指令改变了它的父节点,则需要重新编译,这通常不是一个好主意(无限递归)。
  3. 在(后)链接阶段,元素以相反的顺序链接以编译它们。这意味着当链接指令时,其内容(或子项)已经链接,您可以依赖子项的DOM树。但是,父元素尚未链接。
  4. 所以知道这个如何设计一个具有外部DOM依赖关系的指令?好吧,你需要在编译和链接完成后知​​道DOM的最终状态。为此,我建议至少有两个指令:

    1. 放置在最高级别的master指令,您可以在其中公开可以调用的控制器函数以获取外部DOM数据(基于其DOM树的当前编译和链接状态)。
    2. 嵌套在master指令中某处的子指令,当master指令完成其最终的链接阶段时,可以通知该指令。
    3. 不幸的是,这并不能保证$ watch处理程序(甚至父链接函数)会以意想不到的方式修改DOM。如果您知道哪些指令在起作用,那么您应该能够可靠地使用它。