I added a listener in the code like:
listen: {
afterLayout: function(){
doSomething...
}
}
the function is to render the html tags. But it does not work when the page loaded. I need to force rendering the page like change the size of browser will it work. I wanna know why. "afterLayout" should work automatically after the page loaded right? Or do I miss something?
You are using a wrong config. Instead of listen: { use listeners: {
Here is an example for you: https://fiddle.sencha.com/#fiddle/16gu
Ext.application({
name : 'afterRender Test',
launch : function() {
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
listeners: {
afterRender: function() {
this.update('<div style="width:300px; background-color:red; padding:10px;">Added via afterRender listener</div>');
}
}
});
}
});
I think the event your searching is afterrender.
Afterlayout only fires when the window size change and not on the load.
afterrender event match after the layout of the interested component is loaded.
so you should try with this:
listen: {
afterrender: function(){
doSomething...
}
}
If you must call the same function in all the cases call it on afterrender and on afterlayout
I think your problem can solve viewport.
wrap your application in this component. viewport will listen to window size change and automatically re size it's child elements (your application)
Related
I want to execute JavaScript when all content (e.g. images) has been loaded in my Ember application.
I already tried using didInsertElement() and didRender() hooks, but it looks like they do not wait for background images to load.
Here's what my component's code snippet looks like:
export default Ember.Component.extend({
didInsertElement() {
this._super(...arguments);
Ember.run.scheduleOnce('afterRender', this, function() {
var home =$('#main-outlet')[0];
home.className += " homePage";
startTimer(5);
});
},
});
Any solution or an alternative approach for this?
Ember does not have an event that is equivalent to onload.
However, regarding an alternate approach, you could leverage Ember’s alias for jQuery, in combination with the didInsertElement hook within your component, to achieve the order of execution that you are looking for. Try this:
export default Ember.Component.extend({
didInsertElement() {
Ember.$(window).on('load', this.executeCssAnimations);
},
executeCssAnimations() {
// your CSS and animation logic would go here
Ember.$('.big-background')
.text('NOW READY FOR CSS and ANIMATION UPDATES.')
.css('color', 'yellow');
},
willDestroyElement(...args) {
this._super(...args);
Ember.$(window).off('load', 'window', this.executeCssAnimations);
},
});
The willDestroyElement hook has been included as well, to show proper teardown and removal of the load event listener from window.
I’ve created an Ember Twiddle example to demonstrate this for you.
I'm building an Ember app that needs to size a container DIV to be full window height on load of the application, and then run the same resize function again when transitioning to a new route, and then also on window resize.
On a normal site, I'd do this:
var appUI = {
init: function(){
appUI.sizeContainer();
},
sizeContainer: function(){
var winHeight = jQuery(window).height();
jQuery('#container').height(winHeight);
},
onResize: function() {
appUI.sizeContainer();
}
}
jQuery(document).ready(function($){
appUI.init();
jQuery(window).resize(function(){
appUI.onResize();
});
});
But obviously this won't work in Ember.
This can't be a component, because the #container DIV wraps the entire current view. But with Ember moving away from views, how should I do this?
The only way I came up with was to use a view, and hook onto didInsertElement, but I couldn't figure out how can I do it without having to create a view.js file for every route, that contains the same resize code? And how about the resize event? I thought the application view didInsertElement might work for this, but it only runs once on load.
All my route templates basically follow this patten:
{{top-header}}
{{background-image image=backgroundImage}}
{{side-menu session=session menuOpen=menuOpen}}
<div id="container" class="vert-center route-name">
{{partial "_logo"}}
{{some-component}}
</div>
On loading the application and on window resize can be done pretty much the way you described.
One easy way is to override the renderTemplate hook inside the ApplicationRoute. Within this hook, you can render your application template and then initialize the resize listener on the window object:
// handles on document load and on window change events
App.ApplicationRoute = Ember.Route.extend({
renderTemplate: function(controller, model) {
this.render('application'); // render the application template
appUI.init(); // call the init event on application load
Ember.$(window).resize(function() { // setup resize listener on the window object that will be called when window resizes
appUI.onResize();
});
}
});
As far as resizing each time a route loads, you could implement a generic Ember.Route, let's call it ResizableRoute for example, that calls the appUI.resize() after its template is rendered. This can again be achieved with overriding the renderTemplate hook.
// calls onResize() each time the current route's template is rendered in the DOM
App.ResizableRoute = Ember.Route.extend({
renderTemplate: function() {
// render the template with the same name as the route (assumes you follow ember naming conventions)
this.render(this.routeName);
// call resize since the route is loaded
appUI.onResize();
}
});
Now you can make any other route extend this ResizableRoute and, every time that route's template is rendered, appUI.onResize() will be called.
App.AnyOtherRoute = App.ResizableRoute.extend({
// do other stuff
});
The reason all the calls are made AFTER the template is rendered is because that way the #container element is definitely inserted in the DOM already and can be grabbed using jQuery.
Here is a running jsFiddle example
EDIT
Instead of overriding the renderTemplate hook, another way you could achieve this is to create a ResizeUIComponent that will perform resizing each time your route is loaded. The flaw is that you have to remember to insert this component into each route's template.
App.ResizeUIComponent = Ember.Component.extend({
didInsertElement: function() {
this.$().hide(); // make the component invisible, probably better to do it with css but this is a quick example
appUI.onResize();
}
});
And add this component to all templates (including application) you want to call onResize() each time they load:
{{top-header}}
{{background-image image=backgroundImage}}
{{side-menu session=session menuOpen=menuOpen}}
<div id="container" class="vert-center route-name">
{{resize-ui}} {{!-- add the invisible resize component as the child of #container to ensure necessary rendering order --}}
{{partial "_logo"}}
{{some-component}}
</div>
And you can add a listener on the window object after the init event of the ApplicationController:
App.ApplicationController = Ember.Controller.extend({
onInit: function() {
Ember.$(window).resize(function() { // setup resize listener on the window object that will be called when window resizes
appUI.onResize();
});
}.on('init');
});
Disclaimer: ExtJS - intermediate level;
jQuery - beginner
I've looked for a solution for this but had not found anything yet.
I have both ExtJS and jQuery in one file and I want to be able to execute the jQuery right after the ExtJS is done building a page (is this even possible).
Example:
function renderPage(){
// ExtJS goes here
}
How do I call jQuery after renderPage() is completed?
I tried the following:
$(document).ready(function() {
$("tr").css("background-color", "yellow");
});
$(document).ready(function(renderPage) {
$("tr").css("background-color", "yellow");
});
function renderPage(){
// ExtJS goes here
// ...
$("tr").css("background-color", "yellow");
}
but it doesn't work. I assume it is because the ExtJS is not done rendering the page when jQuery is getting called and it is not finding anything to select.
Additional information:
I know my jQuery works and is connected to the library because I was able to select HTML elements that are rendered before any script ExtJS or jQuery script is run and modify their style.
Thanks!
Ext components fire an afterrender event that you can hook into, but you have to be careful here because it can fire more than once if you render more than once (which is easy to do accidentally). This is an example of a simple app that fires afterrender once for a panel.
Ext.application({
name : 'Fiddle',
launch : function() {
var panel = Ext.create('Ext.Panel',{
renderTo:Ext.getBody(),
title:'myPanel',
items: [
Ext.create('Ext.Button', {
text: 'Click me!!!!',
handler: function() {
alert('You clicked the button!');
}
}),
{
xtype:'toolbar',
items: [{text:'Button 1'}, {text:'Button 2'}],
listeners: {
afterrender: function () {
Ext.Msg.alert('Fiddle', 'done with ext rendering, do jQuery stuff');
}
}
}
]
});
}
});
sencha fiddle: https://fiddle.sencha.com/#fiddle/eqg
I would recommend not mixing these two libraries without a really good reason - Ext has virtually the same DOM helper functionality as jQuery - if you are just changing a class something like Ext.dom.Element.addCls might be more appropriate (http://docs-origin.sencha.com/extjs/4.2.2/#!/api/Ext.dom.Element)
I have a sencha touch application, but want to apply a loading mask to the entire app while the page is loading. (i.e. while the Javascript files etc are loading)
In ExtJS, I used to have a full sized div with a loading image, then as the first action of the "onReady" I used to fade that div out then remove it. Unfortunately, fadeOut() doesnt seem to be available in SenchaTouch
My app definition is as follows:
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('Ext.Panel', {
fullscreen: true,
html: 'Hello World'
});
}
});
Any pointers would be appretiated
You can make use of the Ext.LoadMask class. There is an example:
var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
myMask.show();
When you finish loading some Ajax requests or doing your task and to remove the mask, you can:
myMask.hide();
Hey you can also try this below code while doing ajax request and loading data
var mask = new Ext.LoadMask(Ext.getBody(), {msg:"wait msg..."});
Ext.Ajax.on('beforerequest', function(){
mask.show();
});
Ext.Ajax.on('requestcomplete', function(){
mask.hide();
});
Ext.Ajax.on('requestexception', function(){
});
Here is how I go about it:
Ext.getBody().mask().addCls('black-background');
.black-background {
opacity: 1;
background: black;
}
i have an custom widget in dojo. My Problem is to check some kind of access rules wich are passed to the widget.
if check the rules after the widget is fully loaded everything works fine. But i have to remove some text and buttons before it is displayed.
I've tryted the startup, and postcreate hook (-: is there something like "aftercreate" ?
The first solution I can think of is to begin with hiding the restricted elements and then remove them.
In css:
.hidden{ display: none }
In widget's template for all permissions-sensitive elements:
<div class="${permissionsSensitiveElementsClass}">...</div>
In widget's code:
permissionsSensitiveElementsClass: "",
postMixInProperties: function(){
if(!this.hasPermissions()){
this.permissionsSensitiveElementsClass = "hidden";
}
this.inherited(arguments);
},
startup: function(){
// remove elements if necessary
},
hasPermissions: function(){
// permissions check
},
The final rendering function would be startup(). For widgets which are initially hidden, startup gets called automatically when call is made to show(). dijit.layout.Container has 'addChild(widget)' functionality, which will fire widget.startup() when a/multiple child(ren) are added.
You would benifit from:
http://dojotoolkit.org/documentation/tutorials/1.6/understanding_widget/
Widget lifecycle:
([widget].constructor());
[widget].postscript();
[widget].create();
[widget].postMixinProperties();
[widget].buildRendering();
[widget].postCreate(); // this is the most important one!
[widget].startup();
The true answer to your question lies here;
dojo.declare("mydijit", ["dijit/_Widget"], {
startup: function() {
// call superclass functionality before applying hide on specific elements
this.inherited(arguments);
if(foo) dojo.destroy(this.fooNode);
if(bar) dojo.destroy(this.barNode);
},
onShow: function() {
if(foo.changed || bar.changed) {
// act upon it
}
}
}