[英]Understanding window resize event with scope.$apply with $watch on a function
Recently I found this http://jsfiddle.net/jaredwilli/SfJ8c/ and I am able to get it works. 最近我发现了这个http://jsfiddle.net/jaredwilli/SfJ8c/ ,我能够让它运作起来。
var app = angular.module('miniapp', []);
app.directive('resize', function ($window) {
return function (scope, element) {
var w = angular.element($window);
scope.getWindowDimensions = function () {
return {
'h': w.height(),
'w': w.width()
};
};
scope.$watch(scope.getWindowDimensions, function (newValue, oldValue) {
scope.windowHeight = newValue.h;
scope.windowWidth = newValue.w;
}, true);
w.bind('resize', function () {
scope.$apply();
});
}
})
But the problem is, I don't know how it works? 但问题是,我不知道它是如何工作的? Why
scope.$apply()
? 为什么是
scope.$apply()
? What is the purpose of it? 它的目的是什么? Why
scope.getWindowDimensions
will get updated when window is resized? 为什么在调整窗口大小时
scope.getWindowDimensions
会更新?
The first argument to $watch
can be a string or a function. $watch
的第一个参数可以是字符串或函数。 If you pass a string like $scope.$watch('foo'
, it is watching $scope.foo
. If you pass a function, then the watch is on the return value of the function. Angular will fire the function on every $digest cycle. If the returned value is different than the previous $digest cycle, the callback function (second parameter) will fire. In this code, scope.getWindowDimensions
is a function being passed and when its return value is different, the callback will fire. So, every $digest cycle, if w.height()
or w.width()
have changed, the callback is fired, and the $scope properties are updated. Finally, you have the true
(third) parameter set, which makes the $watch a deep watch, so that Angular will thoroughly check the object, to tell whether it is identical, even though it's a new object every time. Without this, Angular will do a quick check, see that it's a new object, and start an infinite loop. 如果你传递一个像
$scope.$watch('foo'
这样的字符串$scope.$watch('foo'
,它正在观察$scope.foo
。如果你传递一个函数,那么watch就在函数的返回值上$scope.foo
将在每个$上触发函数摘要循环。如果返回的值不同于前一个$ digest循环,则会触发回调函数(第二个参数)。在此代码中, scope.getWindowDimensions
是一个传递的函数,当它的返回值不同时,回调将触发那么,每个$摘要周期,如果w.height()
或w.width()
发生了变化,则会触发回调,并更新$ scope属性。最后,你有true
(第三个)参数集,这使得$观看深度观察,以便Angular将彻底检查对象,判断它是否相同,即使它每次都是一个新对象。如果没有这个,Angular会快速检查,看到它是一个新对象,并且开始无限循环。
scope.$watch(scope.getWindowDimensions, function (newValue, oldValue) {
scope.windowHeight = newValue.h;
scope.windowWidth = newValue.w;
}, true);
Lastly, the code above won't do anything unless a $digest cycle is triggered. 最后,除非触发$摘要周期,否则上述代码将不会执行任何操作。 The following code attaches an event listener to
window
so that the function is fired when the window is resized. 以下代码将事件侦听器附加到
window
以便在调整窗口大小时触发该函数。 scope.$apply()
just triggers a $digest cycle so that scope.getWindowDimensions
will be checked, and the callback will be fired. scope.$apply()
只触发$ digest循环,以便检查scope.getWindowDimensions
,并触发回调。
w.bind('resize', function () {
scope.$apply();
});
With all that said, I find this code to be a bit awkward. 尽管如此,我发现这段代码有点尴尬。 This is how I'd write it.
这就是我写它的方式。 This way makes a lot more sense to me - easier to read, and should be more performant.
这种方式对我来说更有意义 - 更容易阅读,并且应该更高效。
app.directive('resize', function ($window) {
return function (scope, element) {
var w = angular.element($window);
w.bind('resize', function () {
// trigger $digest when window is resized and call `update` function
scope.$apply(update);
});
update(); // initial setup
function update() {
var height = w.height();
var width = w.width();
scope.windowHeight = height;
scope.windowWidth = width;
scope.style = function() {
return {
'height': (height - 100) + 'px',
'width': (width - 100) + 'px'
};
};
}
}
})
First of all its better to google first and then ask your doubt here but anyways if you didn't get anything from it here is the summary:- 首先它最好先谷歌,然后在这里问你的疑问,但无论如何,如果你没有得到任何东西,这里是摘要: -
w.bind('resize',callback)
function binds the resize event of window to w therefore if window resize value of w.height()
and w.width()
change So you are having scope.$watch(scope.getWindowDimensions,callback);
函数将窗口的resize事件绑定到w因此如果
w.height()
和w.width()
窗口调整大小值改变那么你有scope.$watch(scope.getWindowDimensions,callback);
watch the changes in scope.getWindowDimensions which is definately gonna change on changing the window size which in turn calll the callback function. 观察scope.getWindowDimensions的变化,它肯定会在改变窗口大小时改变,而窗口大小又会调用回调函数。
Now why we are using scope.$apply();
现在我们为什么要使用
scope.$apply();
The reson is simple w.bind is out of scope of angular so you need to run the digest cycle which is going to run manually by scop.$apply
. 共振很简单w.bind超出了角度范围,因此您需要运行将通过
scop.$apply
手动运行的摘要循环scop.$apply
。
Sorry for bad english :-P 抱歉英语不好:-P
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.