Bil*_*our 24 javascript angularjs
我有一个Angular指令,它将元素的高度设置为等于浏览器窗口的内部高度(+/-给定的偏移量).该指令响应窗口的"resize"事件并相应地调整其高度.当我的指令范围发出'$ destory'事件时,我删除了对"resize"事件的绑定(我认为保留它会导致一些问题,如果我错了就纠正我).
我不知道如何以"安全"的方式做这个事件分离.如果我在我的应用程序中有多个此指令实例,如果我有其他指令附加到'resize'事件怎么办?
JQuery具有事件命名空间的概念,这似乎是一个很好的解决方案,但Angular的实现(JQLite)不支持这一点.因为我已经在使用Angular,所以我宁愿不使用JQuery,所以我该怎么办?
这是我今天指令的代码
window.angular.module('arcFillClient', [])
.directive('arcFillClientY', ['$window',
function ($window) {
function link($scope, el, attrs) {
var setHeight,
onResize,
cleanUp;
setHeight = function (offSetY) {
var newHeight;
offSetY = offSetY || 0;
newHeight = Math.max($window.innerHeight + parseInt(offSetY, 10)) + 'px';
el.height(newHeight);
};
onResize = function () {
var offset;
offset = attrs.arcFillClientY || 0;
setHeight(offset);
};
attrs.$observe('arcFillClientY', setHeight);
window.angular.element($window).on('resize', onResize);
cleanUp = function () {
window.angular.element($window).off('resize');
};
$scope.$on('$destroy', cleanUp);
}
return {
link: link
};
Run Code Online (Sandbox Code Playgroud)
更新看起来像RTFM的情况,但万一其他人徘徊在这里,这里有一些更多的信息.将原始函数(在我的情况下OnResize)传递给.off()工程以隔离.off()函数的范围.来自文档:
还可以通过在handler参数中指定函数名来删除处理程序.当jQuery {ahem ... JQLite}附加一个事件处理程序时,它会为处理函数分配一个唯一的id.
这是cleanUp我的指令中更新的函数:
cleanUp = function () {
window.angular.element($window).off('resize', onResize);
};
Run Code Online (Sandbox Code Playgroud)
感谢tasseKATT,Karolis和Hans的贡献.
tas*_*ATT 29
通过同样的功能引用off,你传递给on:
window.angular.element($window).off('resize', onResize);
Run Code Online (Sandbox Code Playgroud)
代替:
window.angular.element($window).off('resize');
Run Code Online (Sandbox Code Playgroud)
演示 - 将函数引用传递给off:http://plnkr.co/edit/1rfVPNXl6TrEcuYvzPAj?p = preview
演示 - 不将函数引用传递给off:http://plnkr.co/edit/IsLqSLAzNcHqDnhMty7Q?p = preview
演示包含两个指令,都监听窗口调整大小事件.使用代码和预览之间的垂直分隔符来触发事件.
您会注意到,如果您销毁一个,则另一个将在将函数引用传递给off时继续工作.如果不这样做,两者都会停止工作.
几个星期前,我有同样的问题.
在查看了jqLite源代码(https://github.com/angular/angular.js/blob/master/src/jqLite.js)后,我们看到该on方法添加了该事件,该off方法通过该jqLiteOff函数删除了该事件.
看得更深,我们看到了jqLiteRemoveData电话jqLiteOff.jqLiteRemoveData被称为jqLiteDealoc.jqLiteDealoc被调用在几个地方:jqLiteEmpty,html,replaceWith,和remove.jqLiteEmpty被赋值给元素的empty方法,它清除了jQuery中的元素.html,replaceWith并且remove是jQuery的模仿.
remove()在对元素调用的位置进行搜索时,我们看到它在大多数(如果不是全部)DOM操作逻辑上使用.你可以看到它ngIf,ngSwitch,ngInclude和ngView.
所以我认为Angular会处理事件监听器清理,只要你使用jqLite附加事件并remove()在你自己的DOM操作逻辑中适当调用.使用jQuery包装元素会搞砸很多进程,包括事件监听器清理,但我猜你已经完全清楚了,因为你正在使用它angular.element.