clearTimeout 包裹在闭包中时?
clearTimeout when wrapped in closure?
已更新
HTML
<div class="notification-container" data-bind="foreach: notificationArray">
<notification params="data: $data"></notification>
</div>
JS - 使用 KnockoutJS 创建一个可观察的 'notification' 消息数组。
appViewModel.notificationArray = ko.observableArray([
{ message : 'Test 1' },
{ message : 'test 2' }
]);
使用 Knockout 创建通知组件
ko.components.register('notification', {
viewModel: function(params) {
var data = params.data;
/* set the message to the data.message */
this.message = data.message || null;
/* removes the notification from the array */
this.removeNotification = function() {
appViewModel.notificationArray.remove(data);
};
/* create timer to remove notification after 5s */
/* need to wrap in closure so that inside of the setTimeout it can know about the data object needed to send to the remove() command */
this.timer = function(obj, timeoutLength) {
/* adding return statement per suggestion on Stack Overflow */
return setTimeout(function() {
appViewModel.notificationArray.remove(obj);
}, timeoutLength);
};
this.timer(data, 5000);
/* log will output function structure */
/* clearTimeout will not work */
this.hover = function() {
console.log(this.timer);
clearTimeout(this.timer);
}
},
template: '<div class="notification show-notification" data-bind="event: { mouseover: hover, fastClick: hover }">'
+'<div class="notifications-close clickable right" data-bind="fastClick: removeNotification"><span class="icon icon-x"></span></div>'
+'<div class="notification-text" data-bind="text: message"></div>'
+'</div>'
});
更新以反映工作解决方案
JS
appViewModel.notificationArray = ko.observableArray([
{ message : 'Test 1' },
{ message : 'test 2' }
]);
ko.components.register('notification', {
viewModel: function(params) {
var data = params.data;
this.message = data.message || null;
this.timer = null;
this.removeNotification = function() {
appViewModel.notificationArray.remove(data);
};
this.timer = ( function(self) {
return setTimeout(function() {
self.removeNotification();
}, 5000);
})(this);
this.hover = function () {
clearTimeout(this.timer);
};
this.restart = function() {
this.timer = ( function(self) {
return setTimeout(function() {
self.removeNotification();
}, 5000);
})(this);
}
},
template: '<div class="notification show-notification" data-bind="event: { mouseover: hover, fastClick: hover, mouseout: restart }">'
+'<div class="notifications-close clickable right" data-bind="fastClick: removeNotification"><span class="icon icon-x"></span></div>'
+'<div class="notification-text" data-bind="text: message"></div>'
+'</div>'
});
您没有将 this.timer
设置为 setTimeout
的结果。也许你需要 return setTimeout
?
现在是你的第二个问题。 this.hover
与 this
一起调用。这已在许多其他问题中得到解决。一种方法是在正确的范围内使用 var self = this
以获得正确的 this
或者我当前的偏好是 this.hover = function() {...}.bind(this);
.
编辑:此答案在已接受的答案发布之前开始。发现的问题相似,解决方案略有不同。
1) 您可以将整个 this.timer =
语句替换为
var timerId = setTimeout(function(){
appViewModel.notificationArray.remove(data), 5000);
timerId = 0; // timer finished
};
然后 timerId 在传递给 setTimeout (a.k.a."a closure") 的匿名函数的函数范围内,它和 data
都可以看到。
2)悬停功能也可以利用闭包
this.hover = function() {
console.log("timer " + timerId ? timerId : "finished");
if( timerId)
clearTimeout(timerId);
}
已更新
HTML
<div class="notification-container" data-bind="foreach: notificationArray">
<notification params="data: $data"></notification>
</div>
JS - 使用 KnockoutJS 创建一个可观察的 'notification' 消息数组。
appViewModel.notificationArray = ko.observableArray([
{ message : 'Test 1' },
{ message : 'test 2' }
]);
使用 Knockout 创建通知组件
ko.components.register('notification', {
viewModel: function(params) {
var data = params.data;
/* set the message to the data.message */
this.message = data.message || null;
/* removes the notification from the array */
this.removeNotification = function() {
appViewModel.notificationArray.remove(data);
};
/* create timer to remove notification after 5s */
/* need to wrap in closure so that inside of the setTimeout it can know about the data object needed to send to the remove() command */
this.timer = function(obj, timeoutLength) {
/* adding return statement per suggestion on Stack Overflow */
return setTimeout(function() {
appViewModel.notificationArray.remove(obj);
}, timeoutLength);
};
this.timer(data, 5000);
/* log will output function structure */
/* clearTimeout will not work */
this.hover = function() {
console.log(this.timer);
clearTimeout(this.timer);
}
},
template: '<div class="notification show-notification" data-bind="event: { mouseover: hover, fastClick: hover }">'
+'<div class="notifications-close clickable right" data-bind="fastClick: removeNotification"><span class="icon icon-x"></span></div>'
+'<div class="notification-text" data-bind="text: message"></div>'
+'</div>'
});
更新以反映工作解决方案
JS
appViewModel.notificationArray = ko.observableArray([
{ message : 'Test 1' },
{ message : 'test 2' }
]);
ko.components.register('notification', {
viewModel: function(params) {
var data = params.data;
this.message = data.message || null;
this.timer = null;
this.removeNotification = function() {
appViewModel.notificationArray.remove(data);
};
this.timer = ( function(self) {
return setTimeout(function() {
self.removeNotification();
}, 5000);
})(this);
this.hover = function () {
clearTimeout(this.timer);
};
this.restart = function() {
this.timer = ( function(self) {
return setTimeout(function() {
self.removeNotification();
}, 5000);
})(this);
}
},
template: '<div class="notification show-notification" data-bind="event: { mouseover: hover, fastClick: hover, mouseout: restart }">'
+'<div class="notifications-close clickable right" data-bind="fastClick: removeNotification"><span class="icon icon-x"></span></div>'
+'<div class="notification-text" data-bind="text: message"></div>'
+'</div>'
});
您没有将 this.timer
设置为 setTimeout
的结果。也许你需要 return setTimeout
?
现在是你的第二个问题。 this.hover
与 this
一起调用。这已在许多其他问题中得到解决。一种方法是在正确的范围内使用 var self = this
以获得正确的 this
或者我当前的偏好是 this.hover = function() {...}.bind(this);
.
编辑:此答案在已接受的答案发布之前开始。发现的问题相似,解决方案略有不同。
1) 您可以将整个 this.timer =
语句替换为
var timerId = setTimeout(function(){
appViewModel.notificationArray.remove(data), 5000);
timerId = 0; // timer finished
};
然后 timerId 在传递给 setTimeout (a.k.a."a closure") 的匿名函数的函数范围内,它和 data
都可以看到。
2)悬停功能也可以利用闭包
this.hover = function() {
console.log("timer " + timerId ? timerId : "finished");
if( timerId)
clearTimeout(timerId);
}