嵌套 AngularJS 指令中的查询选择器

Posted

技术标签:

【中文标题】嵌套 AngularJS 指令中的查询选择器【英文标题】:Query selector in nested AngularJS Directives 【发布时间】:2018-03-07 13:23:00 【问题描述】:

我在这段 html 代码中使用了两个指令:

<div animations>
   <h2>Title</h2>
   <span class="animateBtn">Animate!</span>

   <info-section></info-section>
</div>

第一个,是一个属性指令:

angular.module('app').directive('animations', ['$window', ($window: any) => 
    return 
       restrict: "A",
       link: function ($scope: any, element: any, attrs: any) 
        angular.element(document).ready(() => 
            let animateBtns = angular.element(element[0].querySelector('.animateBtn'));
            if (animateBtns && animateBtns.length) 
                for (let i = 0, animateBtnsLength = animateBtns.length; i < animateBtnsLength; i++) 
                    let currentBtn = animateBtns[i];
                    currentBtn.addEventListener("click", function () 
                        .... other code....
                    );
                
            

              ..... other code .....

        );
       
   ;
])

因此,它只是执行一个 querySelector 来选择所有在单击时必须启动某个功能的按钮。 它有效。问题是第二个指令 还包含一个“animateBtn”:

.directive('infoSection', function() 
   return 
       replace: true,
       restrict: 'E',
       template: '<div><span class="animateBtn">Animate with this too</span></div>'
   
);

问题是在第一个指令中(即使我用户(document).ready()),选择器只返回一个元素(标题下的span),它不包括“animateBtn”第二个指令。

您可以在此处找到完整代码:PLNKR

【问题讨论】:

您不应该尝试使用 querySelector 查找其他 DOM 元素。如果你想在指令之间建立父子关系,通过它们的控制器在它们之间进行通信,并让子指令提供它们绑定到父级的 DOM 元素。 我添加了一个Plunker,你可以在这里找到:plnkr.co/edit/ZzcowjuiYO4dCtlyC22Q?p=preview 正如奥利弗已经说过的那样,您的做法是错误的。此外,您永远不应该将事件处理程序放在像这样的角度代码上 - 那是 jQuery 方式。尝试阅读这篇文章,可能会帮助您找出 angularjs 的一些更好的概念:gabrieleromanato.name/… 阅读后尝试以 AngularJS 的方式重新创建它,或者尝试使用 ng-animate 在 angularjs 中制作动画:docs.angularjs.org/api/ngAnimate 感谢@panagulis72 我需要使用角度 $element 而不是 element[0] 处的元素 var animateBtns = angular.element(element[0].querySelector('.animateBtn')); Angularjs v1.6.10 【参考方案1】:

使用 AngularJS 可以使用指令将代码附加到元素而不是查询选择器:

app.directive("animateBtn", function($window) 
    return 
        restrict: 'C',
        link: postLink
    ;
    function postLink (scope, elem, attrs) 
        elem.on('click', function() 

             .... other code....

        );

          .... other code....

    
)

当 AngularJS 框架将元素添加到 DOM 时,上述指令会将点击处理程序和关联代码附加到每个具有类 animateBtn 的元素。


如果在“animations”指令中编写函数,如何在“animatBtn”指令中触发它?我的意思是,在您的代码中,在“.....其他代码....”的第一行中,我如何调用用“动画”指令编写的函数?

使用DDO的require属性访问animations指令的控制器:

app.directive("animateBtn", function($window) 
    return 
        restrict: 'C',
        link: postLink,
        require: '^animations'
    ;
    function postLink (scope, elem, attrs, animations) 
        elem.on('click', function() 

             .... other code....

        );

        //call animations API

        animations.someMethod(args);

    
)

animations 指令中:

app.directive("animations", function() 
    return 
        controller: ctrl
    
    function ctrl($element, $scope) 
        this.someMethod = function(args) 
            //code here
        ;
    
)

欲了解更多信息,请参阅AngularJS Comprehensive Directive API Reference - require

【讨论】:

这似乎是一个很好的解决方案!但是,如果在“animations”指令中编写一个函数,我如何在“animatBtn”指令中触发它?我的意思是,在您的代码中,在“.....其他代码......”的第一行中,我如何调用用“动画”指令编写的函数? 使用 DDO 的 require 属性。查看更新以回答。

以上是关于嵌套 AngularJS 指令中的查询选择器的主要内容,如果未能解决你的问题,请参考以下文章

如何为 ui-bootstrap 日期选择器创建 angularJs 包装器指令?

jQuery 选择器在 AngularJS ng-view 指令中不起作用

在日期时间选择器AngularJs中的特定日期显示颜色

JSS 中的简单选择器和嵌套选择器

ng-readonly 不禁用 angularjs 中的日期选择器

元素选择器中的 SASS 嵌套类选择器不起作用 [重复]