为什么我的指令的链接功能永远不会被调用?

时间:2014-05-18 07:35:09

标签: javascript html angularjs angularjs-directive angularjs-scope

我有这个指令:

    hpDsat.directive('ngElementReady', [function() {
        return {
            restrict: "A",
            link: function($scope, $element, $attributes) {
                // put watches here.
                console.log(" WHAT THE @#%*%$??? ");
                $scope.$eval($attributes.ngElementReady);
            }
        };
    }]);

我从未看到console.log的输出。我宣布一个这样的元素:

<div data-ng-element-ready="console.log(' ------------------------------- COMPILED! ')" data-ng-if="analysis.type" data-ng-show="showBasicHtml" data-ng-include="analysis.type+'Content.html'"></div>

是的,我在宣布存在div元素的控制器之前声明该指令。元素出现,ngShow和ngInclude有效,加载模板中的任何内容都可以正常工作(更多指令,控制器,{{表达式}等)。

如果我用编译函数执行它,编译函数可以工作,但仍然不是链接函数:

    hpDsat.directive('ngElementReady', [function() {
        return {
            restrict: "A",
            compile: function($element, $attributes) {
                console.log("This I do see."); // THIS WORKS!!
                return function($scope) {
                    // put watches here.
                    console.log("But not this. Why???"); // DOESN'T WORK!!
                    $scope.$eval($attributes.ngElementReady);
                };
            }
        };
    }]);

编译函数的console.log工作正常,但返回的链接函数仍然永远不会被执行。

知道为什么链接功能可能不会被触发?

1 个答案:

答案 0 :(得分:3)

错误可能在其他地方。我在jsfiddle中尝试了它,第一个版本可以使用。

<强>的eval()

无论如何,您可能会对$scope.$eval()的作用产生误解:

$scope.$eval()针对范围评估angularjs代码。用于在angularjs中运行任意js代码的JavaScript eval()函数是$window.eval()。有关此内容的更多信息,请访问:Angular.js: How does $eval work and why is it different from vanilla eval?

我测试了与控制器隔离的指令:

<div data-ng-element-ready="console.log('COMPILED!')"></div>

和指令:

app.directive('ngElementReady', ['$window', function($window) {
return {
    restrict: "A",
    link: function($scope, $element, $attributes) {
        console.log("Reached the link fn", $attributes);
        $window.eval($attributes.ngElementReady);
    }
};
}]);

我确实得到了“到达链接fn”的值,$attributes是正确的:

Reached the link fn Object { $$element={...}, $attr={...},  
ngElementReady="console.log('COMPILED!')", more...}

$window.eval()返回COMPILED!

带控制器的

here

在任何情况下,使用eval()执行在属性中编写的代码看起来很危险。任何人都可以修改DOM以在那里运行代码。至少要确保它不会影响任何其他用户或服务器端。

使用ng-if

重现问题

首次评论后编辑: 我尝试将ng-if表达式计算为false here 这次它不显示消息。 这可能是因为为了评估ng-if,yuo必须先编译指令。否则,它只是anuglarjs不知道的代码。但是,因为它已从DOM中删除,所以它永远不会到达链接函数。

AngularJS函数的执行顺序

通常,执行顺序如下(Josh David Miller explains it

<div directive1>
  <div directive2>
    <!-- ... -->
  </div>
</div>

现在AngularJS将通过按特定顺序运行指令函数来创建指令:

directive1: compile
  directive2: compile
directive1: controller
directive1: pre-link
  directive2: controller
  directive2: pre-link
  directive2: post-link
directive1: post-link