【问题标题】:Is it safe to remove dependencies in the controller function when the directive does not seem to use them?当指令似乎不使用它们时,删除控制器函数中的依赖项是否安全?
【发布时间】:2014-03-09 10:06:22
【问题描述】:

下面的控制器似乎没有使用$element、$attrs、$transclude。如果这些参数被注释掉,下面的控制器代码运行良好。

myApp.directive("menu", function () {
    return {
        restrict: "E",
        scope: {},
        transclude: true,
        replace: true,
        template: "<div class='menu' data-ng-transclude></div>",
        controller: function ($scope ,$element, $attrs, $transclude) {
            $scope.submenus = [];
            console.log('[$element]->', $element);
            console.log('[$attrs]->', $attrs);
            console.log('[$transclude]->', $transclude);
            this.addSubmenu = function (submenu) {
                console.log('[addToggleMenu]->');
               $scope.submenus.push(submenu);
            }

            this.closeAllOtherPanes = function (displayedPane) {
                angular.forEach($scope.submenus, function (submenu) {
                    if (submenu != displayedPane) {
                        console.log('[displayedPane]->', displayedPane);
                        submenu.removeDisplayClass();
                    }
                })
            }
        }
    }
});

这里是my working fiddle

自从发帖以来,我了解到在 JavaScript 中,无论列出多少参数,都可以使用任意数量的参数调用函数。在某些语言中,程序员可能会编写两个具有相同名称但参数列表不同的函数,解释器/编译器会选择正确的一个。这就是所谓的函数多态性。在我职业生涯的大部分时间里都使用了函数多态性,我预计会被告知“嘿,你没有使用这个参数”。我也不太明白控制器参数是依赖关系,而链接函数参数是基于顺序的。我仍然难以理解指令内部控制器中的 $scope、$element 或常用参数是否是必需的,哪些是可选的。显然,$ 仅在控制器中需要,而不是在链接中,因为角度服务的 DI 注入......需要大量消化。

特别感谢 Esteban 解释了每个函数内部的特殊伪数组 称为论据。这解释了方程的一半的链接函数。所以我重写了这个问题,希望它可以得到回答。 This excellent explanation, 解决了我的大部分困惑。

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    为什么要删除 $attrs 参数?该指令的参数按特定顺序排列,删除其中任何一个都将导致后续参数不是您认为的那样。

    假设您将链接功能更改为以下内容:

    function ($scope, $iElement, menuController) {
            menuController.addSubmenu($scope); // this will throw  an exception 
                                               // because menuController is actually
                                               // $attrs
    

    这样做的原因是,无论它们是否在指令的链接函数中定义,都会使用传入的相同参数调用该函数。

    function argTest(one, two){
        console.log('argTest.arguments', arguments);
        // even though I don't have three defined, it is still passed in:
        console.log('three is passed in', arguments[2]);
    }
    argTest(1,2,3);
    

    上面的JSFiddle:http://jsfiddle.net/TwoToneBytes/NM8DK/

    【讨论】:

    • Esteban 我在写的时候把它们拿出来,因为我想弄清楚 iAttr 是如何在链接函数中使用的。你说它是菜单控制器。我认为这是范围内的标题。我如何确认我错了?(例如在 Batarang)。即使 $element、$attrs、$transclude 被注释掉,上面的控制器代码也能正常运行。如何验证它们是否需要?
    • 我刚刚做了一个 console.log 和 $iAttr 和 menuController 是完全不同的野兽。 $iAttr 指向每个具有标题的可点击对象,而控制器是 api 供应商。我想从菜单控制器中删除未使用的参数($element、$attrs、$transclude)。我怎么知道什么时候这样做是安全的?
    • 另一方面,在删除 IAttr 时,我可以看到菜单控制器对象上确实引发了异常,所以我应该相信 console.log 还是异常?希望有人能解释一下。
    • 我还在质疑你为什么要删除参数?你想做什么?仅删除参数不会改变传递给参数的内容。
    • Esteban 我试图了解注入代码的责任。我认为它的存在是有原因的。通过删除它,我将指令分解为我可以理解的更小的部分。例如,如果 $transclude 什么都不做,我不想将它包含在我的代码中。我发现很难对我不理解的内容进行单元测试或模拟。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 2019-03-18
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多