Directive Controller And Link Timing In AngularJS

本文探讨了AngularJS中指令控制器与链接函数的执行时机。通过实例演示了当AngularJS遍历DOM树时,如何先实例化指令控制器再进行链接,揭示了两者在编译生命周期中的不同阶段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

I've talked about the timing of directives in AngularJS a few times before. But, it's a rather complicated topic, so I don't mind digging a bit deeper. This time, I'm looking at the timing of directive controllers vs. directive link functions. As the DOM (Document Object Model) is compiled by AngularJS, the directive controllers and link functions execute at different parts of the compile lifecycle.

When AngularJS compiles the DOM, it walks the DOM tree in a depth-first, top-down manner. As it walks down the DOM, it instantiates the directive controllers. Then, when it gets to the bottom of a local DOM tree branch, it starts linking the directives in a bottom-up manner as it walks back up the branch. This doesn't mean that all directive controllers are run before all directive linking; it simply means that in a local DOM branch, the directive controllers are instantiated before they are linked.

To see this in action, I've put together a very simple DOM tree in which each element has a unique (but almost identical) directive. As each directive controller and link function is executed, it will log to the console. This way, we can see the timing of the various methods in relation to the DOM tree structure.

<!doctype html>
<html ng-app="Demo">
<head>
    <meta charset="utf-8" />

    <title>
        Directive Controller And Link Timing In AngularJS
    </title>
</head>
<body>

    <h1>
        Directive Controller And Link Timing In AngularJS
    </h1>

    <div bn-outer>

        <p bn-mid>

            <span bn-inner>

                Woot!

            </span>

        </p>

        <p bn-second-mid>

            Woot, indeed!

        </p>

    </div>


    <!-- Load scripts. -->
    <script type="text/javascript" src="../../vendor/jquery/jquery-2.0.3.min.js"></script>
    <script type="text/javascript" src="../../vendor/angularjs/angular-1.2.4.min.js"></script>
    <script type="text/javascript">
        // Create an application module for our demo.
        var app = angular.module( "Demo", [] );
        // -------------------------------------------------- //
        // -------------------------------------------------- //
        // I demonstrate the timing of directive execution.
        app.directive(
            "bnOuter",
            function() {
                function Controller( $scope ) {
                    console.log( "Outer - Controller" );
                }
                function link( $scope, element, attributes, controller ) {
                    console.log( "Outer - Link" );
                }
                // Return directive configuration.
                return({
                    controller: Controller,
                    link: link
                });
            }
        );
        // -------------------------------------------------- //
        // -------------------------------------------------- //
        // I demonstrate the timing of directive execution.
        app.directive(
            "bnMid",
            function() {
                function Controller( $scope ) {
                    console.log( "Mid - Controller" );
                }
                function link( $scope, element, attributes, controller ) {
                    console.log( "Mid - Link" );
                }
                // Return directive configuration.
                return({
                    controller: Controller,
                    link: link
                });
            }
        );
        // -------------------------------------------------- //
        // -------------------------------------------------- //
        // I demonstrate the timing of directive execution.
        app.directive(
            "bnSecondMid",
            function() {
                function Controller( $scope ) {
                    console.log( "Second Mid - Controller" );
                }
                function link( $scope, element, attributes, controller ) {
                    console.log( "Second Mid - Link" );
                }
                // Return directive configuration.
                return({
                    controller: Controller,
                    link: link
                });
            }
        );
        // -------------------------------------------------- //
        // -------------------------------------------------- //
        // I demonstrate the timing of directive execution.
        app.directive(
            "bnInner",
            function() {
                function Controller( $scope ) {
                    console.log( "Inner - Controller" );
                }
                function link( $scope, element, attributes, controller ) {
                    console.log( "Inner - Link" );
                }
                // Return directive configuration.
                return({
                    controller: Controller,
                    link: link
                });
            }
        );
    </script>

</body>
</html>

  

Before we look at the console output, take note that there are two "mid" branches. This means that AngularJS has two branches to explore before it can fully walk back up to the top DOM node. That said, when we do run the above code, we get the following console log output:

Outer - Controller
Mid - Controller
Inner - Controller
Inner - Link
Mid - Link
Second Mid - Controller
Second Mid - Link
Outer - Link

As you can see, as AngularJS walks the DOM tree, it instantiates the directive controllers on the way down; then, it links the directives on the way back up.

This is an important difference. While you can only access the DOM tree in the bottom-up linking phase, the directive controller can provide a hook into the top-down lifecycle. This can be critical if you have to handle DOM events based on when elements of the DOM tree came into existence. The linking phase can never give you that because it's executed in reverse.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值