2015-09-04 100 views
0

更新clearTimeout封裝在閉包中?

HTML

<div class="notification-container" data-bind="foreach: notificationArray"> 
    <notification params="data: $data"></notification> 
</div> 

JS - 使用KnockoutJS創建 '通知' 消息的可觀察到的陣列。

appViewModel.notificationArray = ko.observableArray([ 
    { message : 'Test 1' }, 
    { message : 'test 2' } 
]); 

使用淘汰賽創建一個通知組件

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>' 
}); 
+1

你在哪裏附加懸停處理程序? –

回答

4

您沒有設置this.timer到的結果setTimeout。也許你需要return setTimeout

現在爲您的第二個問題。 this.hoverthis一起被調用爲別的東西。這已經解決了許多其他問題。一種方法是在正確的範圍內使用var self = this以獲得正確的this或我目前的偏好爲this.hover = function() {...}.bind(this);

+1

除非您的用例比示例更復雜,否則關閉中確實沒有任何點,您可以使用'this.timer = setTimeout(...)' – twinlakes

+0

@Daniel我已更新我的OP以反映您的建議。我可能會錯誤地實施它,因爲它實際上並沒有比以前更好的功能。 – mls3590712

+0

@ mls3590712已更新。 –

0

編輯:此答案在接受答案發布之前開始。所發現的問題與稍有不同的解決方案相似。

1)您可以替換整個this.timer =語句

var timerId = setTimeout(function(){ 
    appViewModel.notificationArray.remove(data), 5000); 
    timerId = 0; // timer finished 
}; 

然後timerId是指傳遞給setTimeout的(又名「封閉」),它的anonomous功能的功能範圍,並data,既可以可見。

2)懸停功能也可以使用閉包。

this.hover = function() { 
    console.log("timer " + timerId ? timerId : "finished"); 
    if(timerId) 
     clearTimeout(timerId); 
}