简体   繁体   English

向AngularJS转换内容添加事件处理程序

[英]Add event handlers to AngularJS transclusion content

What is the proper way to add event handlers to transclusion content? 将事件处理程序添加到翻译内容的正确方法是什么? I do not want the consumers of my directive to add their own click handlers to the document. 我不希望我的指令的使用者将他们自己的点击处理程序添加到文档中。 The directive should handle it. 该指令应该处理它。 But I'm not sure how I correctly add handlers to the content passed with ng-transclude. 但我不确定如何正确地将处理程序添加到使用ng-transclude传递的内容中。

Fiddle around: https://jsfiddle.net/hoe71p0e/12/ (can't get Angular.js and JSFiddle to work; my link function isn't being called) 摆弄: https //jsfiddle.net/hoe71p0e/12/(无法使Angular.js和JSFiddle工作;我的链接函数未被调用)

foo.html foo.html

<my-foo>
    <button type="button">Foo</button>
</my-foo>

foo.js foo.js

return {
    template: "<div class='my-foo' data-ng-transclude></div>"
    link: function($scope, $elem, $attrs, $ctrl, $transclude) {
        $scope.foo = function() {
            console.log("this is never called");
        };

        $transclude(function(clone) {
            for (var i in clone) {
                if (clone[i].localName === "button") {
                    angular.element(clone[i]).attr("data-ng-click", "foo()");
                }
            }
        });
    }
};

expected result (clicking button should call foo) 预期结果 (点击按钮应调用foo)

<div class="my-foo">
    <button type="button" data-ng-click="foo()">Foo</button>
</div>

actual result (clicking button does nothing) 实际结果 (点击按钮什么都不做)

<div class="my-foo">
    <button type="button">Foo</button>
</div>

Notice, the data-ng-click attribute on the button is missing. 请注意,该按钮上的data-ng-click属性丢失。

Also, I've seen several examples with something like this... 另外,我看过几个像这样的例子......

broken.js broken.js

$transclude(function(clone) {
    angular.element(clone).find("button");
});

...but those fail because .find() is not coming back with results, even though the inspector seems to think clone contains a "button". ...但是那些失败是因为.find()没有返回结果,即使检查员似乎认为克隆包含“按钮”。

I can't imagine you are even linking in this directive. 我无法想象你甚至连接这个指令。 In you fiddle, you are missing a few basic requirements eg ng-app="" , restrict: 'E' (required for 1.2.x) in an element style directive, and transclude: true . 在你的小提琴中,你缺少一些基本要求,例如ng-app="" ,在元素样式指令中restrict: 'E' (1.2.x所需),并且transclude: true With remediation of those, we get a working example. 通过这些修复,我们得到了一个有效的例子。 Furthermore, I'm not sure what you are trying to do with $transclude(function(clone) { /*...*/ , but I suspect this is unnecessary. Observe the following... 此外,我不确定你要用$transclude(function(clone) { /*...*/做什么$transclude(function(clone) { /*...*/ ,但我怀疑这是不必要的。请注意以下内容......

<my-foo>
    <button type="button" ng-click="foo()">Foo</button>
</my-foo>

.directive('myFoo', function() {
    return {
        transclude: true,
        restrict: 'E',
        template: '<div class="my-foo" ng-transclude></div>',
        link: function($scope, elem, attrs) {
            $scope.foo = function() {
                console.log('this is called!');
            };
        }
    };
});

JSFiddle Link - working demo JSFiddle Link - 工作演示


Per conversation the most straight forward approach you can take to solve this would be leveraging the $compile service and modifying the attribute on your <button> (once selected) element within your directive link . 根据会话,您可以采取的最直接的方法是利用$ compile服务并修改指令link <button> (一旦选中)元素的属性。 Inject $compile and observe the following... 注入$compile并观察以下内容......

.directive('myFoo', function($compile) {
    return {
        transclude: true,
        restrict: 'E',
        template: '<div class="my-foo" ng-transclude></div>',
        link: function($scope, elem, attrs) {

            $scope.foo = function() {
                console.log('called')
            }

            var button = elem.find('button');
            button.attr('ng-click', 'foo()');
            $compile(button)($scope);
        }
    };
});

JSFiddle Link - $compile demo JSFiddle Link - $compile demo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM