2015-09-04 66 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); 
}