【问题标题】:Get number of child directives in parent directive before link function is executed在执行链接函数之前获取父指令中子指令的数量
【发布时间】:2014-12-05 13:11:54
【问题描述】:

当使用一个指令和多个子指令(使用 require)时,有什么方法可以知道将执行多少子指令?

我可以只计算每次执行子指令的时间(在链接函数中)。但我希望父指令知道在执行子指令的最后一个链接函数之前有多少个子指令。

我需要知道,因为当最后一个元素从子指令传递到父指令时,我需要一些特定的行为..

【问题讨论】:

  • 一个肮脏的解决方案可能是将子指令的数量作为属性传递给父指令。但我希望它自动发生
  • 当您说指令时,还包括ng-repeatng-show 等...您可以吗?
  • 好吧,也许我理解错了,但是您似乎想知道在指令中,嵌套在其中的 DOM 元素中出现了多少指令,对吗?
  • aah 是的,只是我定制的一个,所以不是 ng-repeat、ng-show,..
  • 或者当所有子元素都被嵌入时的事件会非常有用,但它不存在

标签: javascript angularjs angularjs-directive


【解决方案1】:

您可以利用链接分两个阶段完成的事实。您可以首先在“链接前阶段”中注册所有子项,然后在“链接后阶段”中,您可以访问所需的信息。 p>

.directive('parent', function () {
    return {
        controller: function () {
            this.childCount = {
                pre: 0,
                post: 0
            };
        },
        link: function () {}
    };
})
.directive('child', function () {
    return {
        require: '^parent',
        compile: function () {
            return {
                pre: function ($scope, $element, $attrs, parentCtrl) {
                    ++parentCtrl.childCount.pre;
                },
                post: function ($scope, $element, $attrs, parentCtrl) {
                    ++parentCtrl.childCount.post;
                    if (parentCtrl.childCount.post === parentCtrl.childCount.pre) {
                        // ... (this runs only on the last linked child)
                    }
                }
            };
        }
    };
})

这样您就可以在最后一个孩子的链接期间访问该信息。

当然,如果您不需要那么快的信息,您可以在父控制器中注册所有子控制器,然后从父链接后函数运行最后注册的子控制器的方法。

【讨论】:

    【解决方案2】:

    我很确定,如果不在父指令下搜索 DOM,它就无法完成。但我认为在如此专门的指令中这样做是没有问题的。

    所以我会这样做:

    var app = angular.module("app", []);
    
    app.directive("server", function() {
      return {    
        controller: function($element) {                 
          count = $element.find("client").length
          this.call = function() {
            console.log("Server has been called");
    
            count --;
            if (count == 0) {
              console.log("All of them are initialized");
            }
          };
        }
      };
    });
    
    app.directive("client", function() {
      return {
        require: "^server",
        link: function($scope, $elem, $attrs, serverCtrl) {
          serverCtrl.call();
        }
      };
    });
    

    指令看起来像这样:

     <server>
        <client></client>
        <client></client>
        <client></client>
      </server>
    

    在这里您可以看到完整的工作示例: http://jsbin.com/gezewidoba/1/edit?html,js,console

    【讨论】:

      【解决方案3】:

      outer指令和inner指令的执行顺序如下

      Outer - Controller
      Child - Controller
      Child - Link
      Outer - Link
      

      因此您可以使用子指令的控制器连接到父指令的控制器,通过父指令上的一些公开函数。

      然后在inner指令的链接函数中,就可以有逻辑判断元素是第一个还是最后一个等等……

      【讨论】:

      • 从子指令中我调用了控制器中的父方法(例如这里:stackoverflow.com/a/19991997/489856)。这个设置可以吗?
      • 是的,完全正确......尽管您在这两个设置中都需要控制器,但它可能在该设置中。在您提供的示例中,只有父级具有控制器...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      相关资源
      最近更新 更多