I'm using ExtJS 4 MVC.
Is there a way to reload Store every X seconds?
I'd like to put code somewhere to Controller.
setInterval(function(){
// Use Ext.getStore to reference your store from the controller
var myStore = Ext.getStore('YourStore');
// Pass in an object of the changes you want to be made to the store
myStore.proxy.extraParams = { key:'sencha'}; // replace with your own object
myStore.load();
},3000);
FYI in Extjs this is possible to implement via Ext.util.TaskRunner.
A sample code:
var runner = new Ext.util.TaskRunner(),
clock, updateClock, task;
clock = Ext.getBody().appendChild({
id: 'clock'
});
// Start a simple clock task that updates a div once per second
updateClock = function() {
clock.setHtml(Ext.Date.format(new Date(), 'g:i:s A'));
};
task = runner.start({
run: updateClock,
interval: 1000
});
Related
I have the following delay task in the below method:
exportDataToCSV: function () {
var me = this,
grid = this.option.up('grid');
var mask = Ext.widget('processingmessagebox', {
target: grid,
progressMessage: 'exporting',
isProcessing: true,
targetFunctions: {
ConfirmCancelClick: me.stopExportingData
}
});
mask.getViewModel().set({ ShowCancelBox: 'block' });
var grdStore = grid.getStore();
var grdProxy = grdStore.getProxy();
exportData = new Ext.util.DelayedTask(function () {
me.printDataToCSV(grid, mask);
});
exportData.delay(2000);
},
stopExportingData: function () {
exportData.cancel();
}
This is working fine. But, I am trying to cancel the "exportdata" process without using delay task. Any suggestions on this?
You kind of can't. Javascript - and thus ExtJS - is single-threaded. If your code is busy doing something, it can't respond to a cancel button.
In order to make a long-running task cancelable - or even just to allow a progress bar to update - it needs to be broken up into a series of steps. These steps need to then be put on the task queue - something that ExtJS's delayed task does for you.
For something like export data to a CSV, a common approach would be to create a task that exports, say, a dozen records, and then puts another task to read the next dozen.
There are certainly other approaches than using DelayedTask in particular, but they all revolve around the underlying setTimeout or setInterval methods.
Here's an example using a regular ExtJS task, and not DelayedTask:
var readNextDozenRecords = function(indexToReadFrom) { ... }
var writeDataChunk = function(recordsToWrite) { ... }
var taskConfig = {
currentIndex: 0,
interval: 10, // runs every 10ms or so.
run: function() {
var nextDataChunk = readNextDozenRecords(currentIndex);
if (nextDataChunk.length == 0) {
this.stop(); // 'this' scope is the running task.
return;
}
currentIndex += nextDataChunk.length;
writeDatakChunk(nextDataChunk);
}
}
exportData = Ext.TaskManager.newTask(taskConfig);
// The exportData can be manually canceled by calling the `stop` method.
I am using ng-table in my application, I was looking to reset current page to 1 when user changes sort order. I gone through ng-table documentation, but no use.
You should be able to do this via the page() function of NgTableParams:
$scope.tableParams.page(1);
For that, you need to subscribe to the ngTableEventsChannel.afterReloadData(); that is fired after sorting changes. There's an example that logs the events and shows how to subscribe.
This works for me:
var vm = this;
vm.tableParams = new NgTableParams();
vm.recentPage = 1;
ngTableEventsChannel.onAfterDataSorted(function() {
vm.tableParams.page(1);
vm.tableParams.reload();
}, $scope, function(tableParams) {
var reset = tableParams._params.page !== 1 && vm.recentPage === tableParams._params.page;
vm.recentPage = tableParams._params.page;
return reset;
});
I tried to set up a simple app to show the latest message of each member.
At first, it loads the members array.Then I call a function refreshMsg to loop through the array.
Within the loop, I set an timer on it.
However it did not work at all.Could someone five me an hint?
Many thanks.
demo
//show the message for each member and set an timer to refesh
function refreshMsg(){
//loop through members array and set a timer
for(var i=0;i<$scope.members.length;i++){
var cur_member=$scope.members[i];
var name = cur_member.name;
var url_getMsg = "api/getMsg/".name;
var timer = $timeout( function refresh(){
$http.get(url_getMsg).success(function(data){
cur_member.msg=data;
}
)
timer = $timeout(refresh, 3000);
}, 3000);
}
}
})
One of the reasons it is not working correctly is that due to async nature of the call the cur_member would not match the response message as the loop would have moved ahead. The way to do this would be to create another method specifically for setting the $timeout which would create a closure. Better still use $interval
function refreshMsg(){
//loop through members array and set a timer
for(var i=0;i<$scope.members.length;i++){
var cur_member=$scope.members[i];
var name = cur_member.name;
setupRefresh(curr_member);
}
function setupRefresh(member) {
var url_getMsg = "api/getMsg/"+member.name;
var timer = $interval( function(){
$http.get(url_getMsg).success(function(data){
member.msg=data;
}
);
}, 3000);
}
Also remember to dispose all the interval when scope is destroyed.
How I'll get all the parameters that will be send when store.load() is run? I mean, I will not run store.load() but I want to get all request parameters. How I'll do it? (This is a grid's store)
Building off how the source code produces the params, here is a function that will produce the desired results, just know that if you were to updated Extjs beyond 4.1 that it may stop working by the nature of the background code changing:
function getParamsObject(store){
var options = {
groupers: store.groupers.items,
page: store.currentPage,
start: (store.currentPage - 1) * store.pageSize,
limit: store.pageSize,
addRecords: false,
action: 'read',
filters: store.filters.items,
sorters: store.getSorters()
};
var operation = new Ext.data.Operation(options);
var fakeRequest = store.getProxy().buildRequest(operation);
var params = fakeRequest.params;
return params;
}
Once you have loaded your store you can find parameters as below:
store.proxy.extraParams
I have a "Cancel" button on my page which should reverts all the changes I made back to the state it was loaded from server..
I guess I need to store an initial state of Backbonejs model and restore a current (changed) state back to initial.
What is the best way to achieve that?
Thank you
FWIW - i wrote a plugin to handle this automatically, specifically with the idea of "cancel" buttons in mind: http://github.com/derickbailey/backbone.memento
model.previousAttributes() returns all of the previous attributes, while model.changedAttributes() returns all the changed attributes, but with their new values (or false if nothing has changed). So you could combine them to write a cancelChanges method in your prototype :
var MyModel = Backbone.Model.extend({
cancelChanges: function() {
var changed = this.changedAttributes();
if(!changed)
return;
var keys = _.keys(changed);
var prev = _.pick(this.previousAttributes(), keys);
this.set(prev, {silent: true}); // "silent" is optional; prevents change event
},
});
I dont believe there's a single method call for returning a model to its unedited state.. but the unedited values are available individually through model.previous(attribute) and collectively via model.previousAttributes.
Here is what I came up with:
var RollbackEnabledModel = Backbone.Model.extend({
initialize: function() {
this._initAttributes = _.clone(this.attributes);
},
parse: function(data) {
this._initAttributes = _.clone(data);
return data;
},
rollback: function() {
this.set(this._initAttributes);
}
});
Take a look at NYTimes' backbone.trackit. It tracks multiple changes to the model instead of only the most recent change like model.changedAttributes() and model.previousAttributes(). From the README:
var model = new Backbone.Model({id:1, artist:'Samuel Beckett', 'work':'Molloy'});
model.startTracking();
model.set('work', 'Malone Dies');
console.log(model.unsavedAttributes()); // >> Object {work: "Malone Dies"}
model.set('period', 'Modernism');
console.log(model.unsavedAttributes()); // >> Object {work: "Malone Dies", period: "Modernism"}
model.save({}, {
success: function() {
console.log(model.unsavedAttributes()); // >> false
}
});
In addition, the library adds functionality to resetAttributes to
their original state since the last save, triggers an event when the
state of unsavedChanges is updated, and has options to opt into
prompting to confirm before routing to a new context.