【问题标题】:Query selector in nested AngularJS Directives嵌套 AngularJS 指令中的查询选择器
【发布时间】: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

标签: javascript jquery angularjs angularjs-directive angular-directive


【解决方案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 属性。查看更新以回答。
猜你喜欢
  • 1970-01-01
  • 2016-04-02
  • 2019-04-15
  • 2018-05-08
  • 2013-01-19
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多