Created
December 12, 2014 15:19
-
-
Save ksol/db9118c38b0854da43ce to your computer and use it in GitHub Desktop.
Ember.js: cancellable actions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Ember from 'ember'; | |
| export default Ember.Controller.extend({ | |
| actionRunId: null, // This property stores the task id for our action | |
| timerRunId: null, // this property stores the task id for the auto-updating of the timer | |
| currentWaitTime: 0, // The timer (how many seconds are left until the action is executed) | |
| waitTime: 5, // The delay (in seconds) during which you can cancel an action | |
| cancelable: false, // Is there an action to cancel ? | |
| cancelMessage: null, // The message to display to the user | |
| // Note: `cancelable` could actually be derived from `currentWaitTime`, | |
| // and be true when `currentWaitTime` > 0. | |
| // This method updates the timer. It waits one second and then substracts 1 to the timer, | |
| // thus retriggering itself. This goes on until the timer is at 0. | |
| updateCurrentWaitTime: function() { | |
| var _this = this; | |
| // If the timer is > 0, wait a second and subtract one from it | |
| if(this.get('currentWaitTime') > 0) { | |
| var timerRunId = Ember.run.later((function() { | |
| _this.set('currentWaitTime', _this.decrementProperty('currentWaitTime')); | |
| }), 1000); | |
| this.set('timerRunId', timerRunId); | |
| // Otherwise, clear the task id and make sure there is no more task associated to it | |
| } else { | |
| if(!Ember.isBlank(this.get('timerRunId'))) { | |
| Ember.run.cancel(this.get('timerRunId')); | |
| this.set('timerRunId', null); | |
| } | |
| } | |
| }.observes('currentWaitTime'), | |
| // This method "enqueues" the given callback (your action) and wait | |
| // x seconds before executing it, allowing you to cancel it | |
| waitBeforeAction: function(callback) { | |
| var actionRunId; | |
| var self = this; | |
| var delay = this.get('waitTime') * 1000; | |
| // Starting now, there's an action waiting to be executed, meaning we can cancel it. | |
| // We're setting the timer here, and this triggers the observer above. | |
| this.setProperties({ | |
| cancelable: true, | |
| currentWaitTime: this.get('waitTime') | |
| }); | |
| // Keepking track of the "task id". Necessary to cancel it later | |
| actionRunId = Ember.run.later((function() { | |
| // At this point, we're executing the action, so there's nothing that can be canceled. | |
| self.setProperties({ | |
| cancelable: false, | |
| cancelMessage: null | |
| }); | |
| // Executing the callback in the context of the controller | |
| callback.call(self); | |
| }), delay); | |
| this.set('actionRunId', actionRunId); | |
| }, | |
| actions: { | |
| // This is a regular action, executed right away | |
| someAction: function() { | |
| // ... | |
| }, | |
| // This action handles the cancel logic | |
| cancelAction: function() { | |
| // Resetting the properties here | |
| this.setProperties({ | |
| cancelable: false, | |
| currentWaitTime: 0, | |
| cancelMessage: null, | |
| }); | |
| // Cancelling the action in the run loop, clearing the saved ID | |
| if(!Ember.isBlank(this.get('actionRunId'))) { | |
| Ember.run.cancel(this.get('actionRunId')); | |
| this.set('actionRunId', null); | |
| } | |
| }, | |
| // Assignment: accept/refuse logic | |
| importantAction: function() { | |
| this.set('cancelMessage', 'You just did something that can cancel'); | |
| this.waitBeforeAction(function() { | |
| // Your action logic goes here | |
| }); | |
| }, | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment