从 Angular 指令调用的函数访问属性/$element 上下文

XML*_*XML 2 html javascript angularjs

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


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


在本例中,我只是.active根据 的值,将上下文类添加到 nav 元素$location.path(),按照这篇文章这篇文章。但是,在这些示例中,您需要显式且冗余地将属性内容的副本href作为参数传递给getClass()您调用的函数ng-class。但是,是否有一种方法可以以编程方式href从内部访问该属性getClass(),并避免重复地将相同的内容作为参数传递?

例如,一个具有getClass()我想象的功能的控制器可以工作:

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

然后你可以简单而优雅地调用它:

<a ng-class="getClass()" href="/tasks">Tasks</a>
Run Code Online (Sandbox Code Playgroud)

而不是:

<a ng-class="getClass('/tasks')" href="/tasks">Tasks</a>
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*esh 5

你实际上可以这样做......但你不应该这样做。哈哈...

这是如何执行您所要求的操作...

在您的标记中,将 $event 传递到您的函数中。

<a ng-click="test($event)" href="whatever">Click Me</a>
Run Code Online (Sandbox Code Playgroud)

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

$scope.test = function($event) {
    alert($event.target.href);
};
Run Code Online (Sandbox Code Playgroud)

现在这就是为什么你可能不应该这样做:

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

也就是说,如果您所做的所有事情只是获取一个值,那可能没问题,但您仍然在某种程度上将控制器与标记耦合。如果您要对该 DOM 元素执行任何其他操作,则您就无法保留了。

  • 一年后......我同意@blesh。自定义 Angular 指令确实是正确的选择。这比你想象的要容易,花时间学习后,你很快就能把它们搞出来。感谢您的好建议,@blesh! (3认同)
  • 是的,如果有事件,这有效,但在 ng-class 的情况下没有事件。 (2认同)