从Angular指令调用的函数访问Attributes / $元素上下文

时间:2012-10-25 22:21:17

标签: javascript html angularjs

directive definition中,有一个用于访问$ element和$ attrs的API,因此您可以返回调用该指令的元素。使用像ng-class这样的标准指令调用自定义函数时,如何访问$ element和$ attrs?


编辑:我知道这不是惯用法。这个问题适用于快速原型,这对于Angular的许多功能都很有用。只是不是关于可持续性,关注点分离等等。我主要关心的是速度。因此,能够使用内置指令和快速控制器方法快速敲击内容实际上可以成为一种美德,并且可以赢得在未来实现更全面,更正确的实施的机会......


在这种情况下,我只是根据.active的值this postthis one向nav元素添加了一个上下文$location.path()类。但是,在这些示例中,您需要显式并冗余地将href属性的内容副本作为参数传递给您从getClass()调用的ng-class函数。但是,有没有办法以编程方式从href内访问getClass()属性,并避免将相同内容作为arg冗余传递?

例如,一个具有getClass()功能的控制器,就像我想象的那样:

function navCtrl($scope, $routeParams) {
    $scope.getClass = function($element, $attrs) {
        if ($location.path().substr(0, path.length) == $attrs.href) {
            return "active"
        } else {
            return ""
        }
    }
}

然后您可以简单而优雅地致电:

<a ng-class="getClass()" href="/tasks">Tasks</a>

而不是:

<a ng-class="getClass('/tasks')" href="/tasks">Tasks</a>

(我认识到另一个选择是创建一个执行此操作的自定义指令,但是现在我只想弄清楚是否可以从被调用的控制器函数中访问$ attrs和/或$元素指令。谢谢!)

3 个答案:

答案 0 :(得分:4)

你实际上可以这样做...... 但你不应该这样做。大声笑......

以下是如何做你要求的......

在你的标记中,将$ event传递给你的函数。

<a ng-click="test($event)" href="whatever">Click Me</a>

然后在你的控制器中,获取事件的目标元素:

$scope.test = function($event) {
    alert($event.target.href);
};

现在这就是你可能不应该这样做的原因:

如果您引用DOM或操纵控制器中的DOM,则会危及依赖注入以及Angular结构中的关注点分离。当你测试你的函数时,你仍然可以将$ event作为依赖项注入,但是根据你在该函数内部所做的事情,你可能仍然破坏了你的DI,并且你试图让一个控制器做一个指令工作(试图阻止你的控制器与你的标记紧密耦合)

那就是说,如果你所做的只是得到一个值,它可能很好,但你仍然在某种程度上将你的控制器耦合到你的标记。如果您正在使用该DOM元素执行任何其他操作,那么您将无法进行预订。

答案 1 :(得分:2)

我认为你不能那样做。角度原理是避免直接从控制器访问DOM。您已经在Angular中确定了两个选项:

  • 将href作为param传入,即getClass('/ tasks')
  • 或编写自定义指令

或者,如果该类纯粹是表示性的,并且不影响应用程序的运行方式,那么您可以忽略angular并使用快速而脏的jQuery函数为您完成工作。

缺乏与DOM的直接交互起初可能有点奇怪,但从长远来看,这是一个天赐之物,因为你的代码库不断增长,变得更复杂,需要更多的测试。

答案 2 :(得分:0)

这是一个完全不同的答案:你不需要Angular来改变基于href的样式。您可以使用CSS选择器。

在你的风格中:

a[href="/something"] {
    background-color: red;
}

这与您在ng-class中可能做的任何事情相结合应该是您需要的一切。