我正在使用onsen UI(基于角度)+ phonegap开发应用程序。 所以我在角度控制器中有一个JQuery单击事件,这就是问题所在。
当我返回页面堆栈并再次运行时,它会多次触发点击事件。
我在角度控制器中使用jquery click事件,因为我必须在此事件中使用Onsen UI Service。所以我必须在控制器内声明这个事件。但这就是问题所在。看:
module.controller('ListController', function($scope, EventsService, OneEventService) {
$scope.events = EventsService.getPopular();
//this is the event that is triggering many times
$(document).on("click",".item-from-list",function(e){...}
我尝试使用$(element).click(func)
但它无法获取DOM元素。
然后我使用$(document).on("click", elem, func)
那么我该如何解决这个问题呢?
答案 0 :(得分:8)
这是因为您每次初始化控制器时都会在文档上注册click
处理程序。每次导航到其他页面/视图并再次返回同一页面时,控制器都会被初始化(即控制器中的所有代码都被执行),因此jQuery每次都会在文档上添加一个新的click事件监听器。
您可以通过两种方式解决此问题。
方法-1:强>
使用jQuery' off()
取消注册现有的点击处理程序,然后再添加新的点击处理程序。
`$(document).off().on("click",".item-from-list",eventHandlerFn);`
方法-2:强>
使用基于角色的基于范围的事件处理程序,如ng-click
,当控制器超出范围时,即当您移动到新页面时,会自动取消注册。
<div class='item-from-list' ng-click='handleClick()'></div>
module.controller('ListController', function($scope) {
$scope.handleClick= function(){ /* handle click event here */ };
}
AngularJS的一个基本原理是将DOM操作保留在控制器之外,因此我建议第二种方法来解决您的问题。甚至还有第三种方式使用自定义指令,在这里您可以获得对元素的引用,并且可以使用jQuery或使用默认的jQLite()来注册您的单击处理程序。
module.directive('registerClick',function(){
return {
restrict : 'A',
link: function (scope, element, attrs) {
/* register your event handler here */
element.on('click', clickHandlerFn);
/* As we're explicitly registering the handler, we need
to de-register it, once your element is destroyed like below */
element.on('$destroy', function () {
element.off('click', clickHandlerFn);
});
}
};
});