为什么我不能在AngularJS链接函数中使用vanilla javascript(eventlistener)?

时间:2015-06-02 18:33:24

标签: javascript angularjs angularjs-directive

所以我只是测试一些东西而且我正在编写这样的指令:

HTML

<div ng-app="app">
    <my-directive>
        hi {{name}}
    </my-directive>
</div>

JS

angular.module("app", [])

.directive("myDirective", function () {
    return {
        scope:true,
        restrict: "E",
        link: function (scope, elem, attr) {
            scope.name="yourname";
            elem.onclick = function () { console.log("change name");}
        }

    }
})

但是onclick函数永远不会触发。而且我知道这不是我应该如何在Angular中正确编写,但它只是我在飞行中所做的事情。但是,这有效:

angular.module("app", [])

.directive("myDirective", function () {
    return {
        scope:true,
        restrict: "E",
        link: function (scope, elem, attr) {

            scope.name="yourname";
            elem.on("click", function () {console.log("change name")});
        }

    }
})

这里有一个小提琴:fiddle

这里发生了什么?它是否在Angular世界之外,我应该使用scope.apply或其他东西来使它工作。我只是好奇为什么香草javascript在这种情况下不好。但这也是让我自己专注于思考Angular方式的一个很好的教训。

也许有人可以解释发生了什么? TIA

2 个答案:

答案 0 :(得分:5)

这是因为链接函数中的elem是一个jQuery对象。您应该使用elem[0]获取html dom元素,然后尝试。

angular.module("app", [])

.directive("myDirective", function () {
    return {
        scope:true,
        restrict: "E",
        link: function (scope, elem, attr) {
            scope.name="yourname";
            elem[0].onclick = function () { console.log("change name");}
        }

    }
})

答案 1 :(得分:2)

这是一个让您的原始代码正常工作的新小提琴,但问题中的代码现在看起来非常不同。

一个问题是你的“name”属性没有绑定,因为你有一个隔离范围,其中设置了名称,但是然后transclude:true导致angular绑定到外部作用域,因此名称永远不会显示。此外,没有模板可以拉入已转换的内容,只留下一个空的html元素。这个新的小提琴主要是你的原始代码,但事件处理程序无需直接转到dom元素,就像在其他发布的答案中一样。

https://jsfiddle.net/ghkfjjh6/9/

angular.module("app", [])

.directive("myDirective", function () {
    return {
        transclude: true,
        restrict: "A",
        template: '<div ng-transclude></div>',
        link: function (scope, elem, attr) {
            console.log("link ran!");
            scope.name = "miek";
            console.log(scope);
           elem.on('mouseenter', function() {
               console.log("entered");
            })
        }

    }
})

<div ng-app="app">
    <div my-directive>
        hi {{name}}!
    </div>
</div>