使用jQuery绑定AngularJS元素指令上的事件
我在AngularJS中有一个指令:
module = angular.module("demoApp", [], null); module.directive('sample', function () { return { restrict: "E", transclude: true, replace: true, template: "", controller: function ($scope, $element) { this.act = function (something) { //problematic line HERE $element.trigger("myEvent.sample", [something]); }; } }; }) .directive('item', function () { return { restrict: "E", require: "^sample", transclude: true, replace: true, template: "", link: function (scope, element, attributes, parentController) { element.on("click", function () { parentController.act(this.innerText); }); } } });
在我的HTML中,我使用它:
1 2
哪个将呈现为:
我希望能够通过jQuery手动触发事件:
$("#myElement").on("myEvent.sample", function (e, something) { alert("click: " + something); });
我想在点击链接时触发此事件。
如果我在sample
指令上将replace
属性设置为false
,则它可以正常工作。 我想这是因为在事件被触发的时刻,元素sample
不再存在,因此它将被内部模板替换。
那么,我该如何做到这一点?
如下面的答案所示,这样做不会达到我的目的:
$($element).trigger("myEvent.sample", [something]);
请在下面找到小提琴
小提琴
触发器是一个jquery函数,它将适用于正确的处理程序。
$(element).trigger("myEvent.sample");
希望这可以帮助
这是更新的小提琴: http : //jsfiddle.net/3u3zh/1/
有几点值得注意:
-
由于角度转换DOM的方式,我建议在主体上附加所有自定义侦听器,然后按事件目标过滤它们。
$('body').on('myEvent.sample', 'target-selector-expr', handler)
这么做的。 例如,如果在ngRepeat
ed元素上使用自定义事件侦听器,ngRepeat
不会执行处理程序,因为在尝试将事件附加到它们时这些元素不存在。 -
看起来angular的jqLite实现在触发事件时有些缺乏function。 因此,我将
sample
的元素包装在jQuery($($element)
)中,否则额外的数据将无法到达处理程序。
最终模板:
- 1
- 2
JS:
var myApp=angular.module('myApp',[]); myApp.directive('sample', function () { return { restrict: "E", replace: true, transclude: true, template: "", controller: function ($scope, $element) { this.act = function (something) { $($element).trigger("myEvent.sample", [something]); }; } }; }) .directive('item', function () { return { restrict: "E", require: "^sample", transclude: true, template: "", link: function (scope, element, attributes, parentController) { element.on("click", function(e) { parentController.act(this.innerHTML); }); } } }) $(document).ready(function(){ $("body").on("myEvent.sample", '#myElement', function (e, something) { alert('clicked: ' + something); }); });