Data arrived event - extjs

I am using Extjs 4.1. I need to identify event on grid when data renderred and arrived.
I checked ''afterrender' event. But it fires to early
grid.on('afterrender', function () {
alert(333);
});
Please advice

You're correct grid rendered event would fire after grid was rendered not after the data is displayed. What about subscribing to the store load event?
store.on('load', function() {
...
})

If you simply need to know when the grid has first loaded data, use the Ext.grid.Panel viewready event, it fires when the data has been loaded in and the grid rows have been rendered.
Example:
this.control({
'mygridpanel': {
// select the first record
viewready: function(grid) {
var store = grid.getStore(),
view = grid.getView(),
selModel = grid.getSelectionModel();
if (store.getAt(0)) {
view.focus();
selModel.select(0);
}
},
},
});
This example is configured in the init function of a controller using the MVC pattern, I'm not sure if you are using MVC pattern? The snippet in your comment should work fine either way though.
Also this event passes the Ext.grid.Panel object that fired it as the first argument, as you can see from the example above, you can use that to get a reference to your grid and perform whatever logic you need to do on it in your handler.

Related

How to capture the Icheck checked event in backbone

How to capture the iCheck change event in backbone view.
I am unable to find any reference and using normal change event is not working.
My solution for events backbone.js is
events: {
'ifChanged #myIdCheckbox': 'changed'
},
First of all, you should try to search on the Internet almost all plugins have a web page, this one for example: http://icheck.fronteed.com/
But anyway, to listen to click event Ichecks, you must use ifChanged or check
$('input').on('ifChanged', function (e) {
var value = $(this).val();
....
});
You can also use an ID to select a checkbox just by typing: $('#Id').....

Backbone or Marionette callback for when a Collection item displays on the page?

Question
What is a good way to run some code only after a Backbone or Marionette Collection item has displayed onto the page?
More info
The reason I need to do this is because I am using google charts. The charts do not render quite right unless they are actually visible on the page when they are being rendered (ie: not hidden explanation). It appears that when the collection item's onRender function is called, the view is not quite rendered completely on the page.
The "fix" I'm currently is to use setTimeout to render the charge a half second after onRender is called. This works, but is an ugly hack:
Backbone.Marionette.ItemView.extend({
...
onRender: function(){
var chart = ...;
var chart_data = ...;
var options = ...;
setTimeout(function(){
chart.draw(chart_data, options)
},
500
);
}
...
})
I've read in other places that onShow works, but if I understand correctly, this method only is called when working Marionette regions.
Unfortunately, Marionette's onRender method doesn't mean that the object is actually added to the DOM.
If you were using Marionette's regions, then onShow would probably do the job because of the timing. But as it can be detached from the DOM there is no guarantee that views are actually displayed.
The actual clean solution is to use the onAttach event added to Marionette v2.3. Hope this will solve your problem — but I'm confident with that =)
otherwise, you can use a plugin like jquery.inview to get a inview event once a given element becomes visible:
Backbone.Marionette.ItemView.extend({
events:{
'inview #chartContainer': 'renderChart'
},
renderChart: function(){
var chart = ...;
var chart_data = ...;
var options = ...;
chart.draw(chart_data, options)
},
...
})

Prevent Backbone event from triggering more than once, how to check if event is registered already?

In my router object, I created an event object to share among my views
I pass the event object to my views
I register events to this shared object like this
var productCatalogView = Backbone.View.extend({
initialize: function (options) {
//bind alert event to sharedEvents
options.sharedEvents.bind("alert", this.alert,this);
},
alert: function () {
alert('alerted');
}
});
//The following view triggers the alert event
var testView = Backbone.View.extend({
initialize: function (options) {
this.sharedEvents = options.sharedEvents;
},
events: {
'click #test': 'triggerAlert'
},
triggerAlert: function (e) {
this.sharedEvents.trigger("alert", null);
}
});
THE PROBLEM:
The problem I experience is that the first time I click on the button which triggers the alert event (second view), the alert event gets called once (good), this causes the first view to be re-rendered by triggering the route passing search parameters, therefore creating the first view and binding the sharedEvents again, hence when I trigger the alert event a second time, it gets triggered twice (bad), the next time I repeat the same process, it gets triggered 3 times, and so on and so forth. I guess it has to do with the event binding in the first view, it occurs more than once, i.e each time the view is initialized (if I am correct)
please how can I make the binding of the event occur once.
Here is my router which shows how I initilze the views:
var Router = Backbone.Router.extend({
sharedEvents:_.extend({},Backbone.Events),
catalog: function (id) {
//....unecessary code left out
var productView = new ProductView({sharedEvents:this.sharedEvents});
this.renderView(productView);
this.renderView(new testView({sharedEvents: this.sharedEvents }));
}
renderView: function (view) {
if (null != this.currentView) {
this.currentView.undelegateEvents();
// this.currentView.remove();
}
this.currentView = view;
this.currentView.render();
}
});
I have tried this solution but problem persists, thanks
Try using Backbone.Events' listenTo method instead of the bind method. Then, in your renderView(), call this.currentView.remove instead of this.currentView.undelegateEvents.
Rationale:
I believe in your renderView() method, you are using undelegateEvents() thinking it releases all event listeners created by your view. It only releases events bound on to your view's $el element. However, using remove() on the view releases events bound to the $el as well as events created using this.listenTo() (and this.listenOnce()).
Now once you render another view, the old currentView will be properly released and you'll only get one alert.

ExtJs. Setting form values on load and change listeners

I need "good style" advice. I have a form which is populated from json. The code which populates the form is put inside render listener. The problem is, many form elements have change listeners, so when the form is populated these change listeners are triggered. I want to prevent this unwanted behavior.
// many form elements with change listeners come here
listeners:{
render:function(){
var frm=this.getForm();
Ext.Ajax.request({
url:'../handlers/instruct.handler.php?id='+id,
method:'POST',
params:{action:'params'},
success:function(result,request){
json=Ext.decode(result.responseText,1);
frm.setValues(json); // form population
// triggers change listeners
}
});
}
}
PS. I use ExtJs 4.2
You could suspend events on the fields:
var fields = form.getForm().getFields();
fields.each(function(f) {
f.suspendEvents();
});
form.setValues(json);
fields.each(function(f) {
f.resumeEvents();
});

Trigger click event from one file from another in BackboneJS

in my project i am not able to trigger click event registered in one backbone view from another backbone view. its actually i am having a file type input placed hidden from the user and i need to trigger the file type input.
var FileView = Backbone.View.extend({
....
events : {
"click .delete-image" : "deleteFile",
}
....
});
var FilesView = Backbone.View.extend({
....
events : {
"click #attach" : "attachFile",
},
attachFile : function() {
this.fileView.trigger("click .delete-image");
}
....
});
but i tried like this the event is not get triggered. how is it possible.
the events hash attaches itself to the jquery element that represents the view, not the backbone view itself. So you would most likely have to do something like this:
attachFile : function() {
$('.delete-image', this.fileView.$el).trigger("click");
}
but I would discourage this kind of non-pattern and instead work towards using something we call an Event Aggregation pattern. You can find a collection of really good SO solutions next:
fire an event from one view to another in backbone
Backbone.js global events
Multiple view on same page with backbone.js

Resources