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

相關問題