4

将事件处理程序添加到transclusion内容的正确方法是什么?我不希望我的指令的使用者将自己的点击处理程序添加到文档中。该指令应该处理它。但我不知道如何正确地将处理程序添加到通过ng-transclude传递的内容。将事件处理程序添加到AngularJS transclusion content

摆弄:https://jsfiddle.net/hoe71p0e/12/(不能得到Angular.js和的jsfiddle工作;我的链接功能不会被调用)

foo.html

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

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()"); 
       } 
      } 
     }); 
    } 
}; 

预期的结果(点击按钮应调用foo)

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

实际结果(点击按钮,什么都不做)

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

通知,按钮上的data-ng-click属性丢失。

而且,我已经看到了几个例子有这样的事情...

broken.js

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

...但这些失败,因为.find()没有与结果回来了,即使检查员似乎认为克隆包含“按钮”。

+0

这不是很明显的你正试图在这里完成的。你试图达成的目标是什么?我不确定我是否遇到过以这种方式增加其他内容的指令。 – Claies

+0

我在想OP只是想在一个transcluded指令中调用他的'ng-click'事件,并且正在解释他们到目前为止所尝试的内容 – scniro

+0

我已经添加了一个注释来解释我不希望我的指令的使用者被要求编写点击处理程序来使指令工作。基本上,我的指令应该有一个必需的“按钮”子,但指令需要处理按钮的点击行为;消费者不应该负责。 –

回答

2

我无法想象你甚至连接这个指令。在你小提琴中,你缺少一些基本要求,例如ng-app="",restrict: 'E'(对于1.2.x是必需的)在元素样式指令中,以及transclude: true。随着这些修复,我们得到一个工作的例子。此外,我不确定你想用$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 - 工作演示


每谈话最直接的方法,您可以采取来解决,这将借力$compile服务并修改link指令中<button>(一旦选定)元素的属性。注入$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演示

+0

我向你保证,在我工作的实际代码中,链接函数被调用。总的来说,我的指令的消费者不应该添加他们自己的点击处理程序。这就是为什么我使用$ transclude(不正确,显然...) –

+0

好吧我想我明白你在做什么。应该有几种方法来做到这一点。看看[小提琴](https://jsfiddle.net/xuyjv804/),让我知道这是你倾向的方向吗? @richremer – scniro

+0

和[另一种方式](https://jsfiddle.net/xuyjv804/1/)我们可以通过'$ compile'执行它 – scniro

相关问题