I am using Angular2 with ionic, and I have this sort of component:
class MyComponent implements OnInit, OnDestroy {
ngOnInit() {
console.log("init");
socket.on("something", this.something.bind(this));
}
ngOnDestroy() {
console.log("destroy");
socket.remove("something", this.something.bind(this));
}
}
To open this page, I write this.nav.setRoot(MyComponent). Now my page is showing MyComponent, and the socket is listening for "something".
To refresh it, I write this.nav.setRoot(MyComponent) again. Now my page is showing MyComponet, and the socket is not listening for "something".
The console output is:
init
init
destroy
Why is it first run ngOnInit of the second component, and only then ngOnDestroy of the first one?
Is there a way to first call the destroy, and then the init?
Is there another way I should handle my socket?
As I understand this, you cannot really control, what should happen first in between ngOnInit of the second component and ngOnDestroy of the first one. These hooks, from 2 different components, at least, are not dependent on each other. Whether hooks on the same component are dependent on each other. Read this.
May be, this depends on whatever gets triggered faster at the moment.
In this case, what you can do is, you can move your code from ngOnDestroy before calling this.nav.setRoot(MyComponent).
Also, if the requirement does not suite this kind of code, you can try to refresh a particular type of UI component which needs to be refreshed than refreshing the entire component like this.nav.setRoot(MyComponent).
You can refresh a particular UI component using DOM using document.getElementByID('myDiv') type of operations.
Hope this helps. If not, please mention the specifics.
Apparentally, ionic has it's own lifecycle functions, as mentioned here.
Instead of ngOnInit use ionViewDidLoad
Instead of ngOnDestoy use ionViewWillLeave
Works like magic.
Related
I would like to create a plugin mechanism for my custom wrapper around AgGrid. Currently I am doing so with an interface like this:
export interface IGridPlugin {
onGridReady: (e: GridReadyEvent) => void;
}
Then, in my wrapper around AgGrid, I add an onGridReady event handler that goes through the supplied list of plugins and invokes their onGridReady method one at a time. They can then perform any initialization that they require - like adding event handlers via e.api.addEventListener
gridOptions.onGridReady = (e: GridReadyEvent) => {
plugins?.forEach(plugin => plugin.onGridReady(e));
}
Unfortunately, the onGridReady event appears to only fire after the grid initially loads and renders. One of the plugins I've created will restore the grid state from url params when onGridReady fires, and will subsequently keep the url params updated as the grid state changes.
Since onGridReady fires after the initial rendering, there's a small delay where the grid is displayed without the application of the preserved grid state in the url. I was hoping to find an earlier event that might make more sense for this.
Alternatively, I suppose I could allow the plugins to modify the gridOptions directly before the grid is even constructed... but using events feels a little safer - preventing one plugin from setting itself up as the sole event handler for something that other plugins may want to use and accidentally disable some/all of the functionality of other plugins.
Is there a better event or alternative mechanism for adding such plugins to AgGrid? I would like to make sure that the plugins have access to the api and columnApi instances in any approach taken.
I am using cdp (https://github.com/mafredri/cdp) in order to use devtools protocol to generate a pdf of a page. But first I need to know when the page is completely loaded. I found that the networkIdle event can help me to know when this occurs. But, I have troubles because the networkIdle event sometimes fired twice. Then I need to know when this one is fired
There are two parts for what you're looking for.
First of all, the reason the event is fired twice. When a new tab (target) is created, the first page it loads is about:blank. You get lifecycle events for this page as well. The second time the load event is fired is the one you're looking for (if you're using Page.lifecycleEvent).
Now, to handle the second matter - there are also other events you can use. The basic one for page loading is Page.loadEventFired, which, as far as I recall, will only be fired for the actual page (but I could be wrong about this one).
Important note: If you're using lifecycle events, they are fired for each frame separately, meaning that the main frame might finish loading before the sub frames are loaded. Page.loadEventFired has a different behavior and waits for all frames to fire their load event.
Here is a good article on the page lifecycle api.
Another possible solution could be:
document.onreadystatechange = function () {
if (document.readyState === 'complete') {
run the screenshot code...
}
}
I have a Home Page, inside that I have created one component RecentlyViewedProductComponent.
My problem is:
when I navigate to /home by using
this.router.navigate(['/home']);
the ngOnInit() inside RecentlyViewedProductComponent is not working. When I close the app and open it again, that only it is working .
How to solve this problem?
It sounds like you are not using the right lifecycle event.
Have you looked at the documentation here:
https://ionicframework.com/docs/angular/lifecycle
It says that ngOnInit() is:
Fired once during component initialization. This event can be used to initialize local members and make calls into services that only need to be done once.
If you want it to be called every time you navigate to the home page then you want to replace this with something like ionViewWillEnter():
Fired when the component routing to is about to animate into view.
There is actually some guidance at the end of the docs page that you might find interesting which explains when to use each life cycle method.
Modals and Notifications are components that are appended to the body. So they work little different than normal components. In my App, I can think of two ways of implementing them and I am not sure which one is better.
No stores
In this approach, I create a NotificationHelper class which has a create method. Inside that, I create a new container node, append it to the body and then call React.render(, container);
So any component can call NotificationHelper.create() and it will create a notification. Notification component that manages it's lifecycle and closes when the timer expires or somebody clicks on the close button.
The problem is often times, I need to show notification on the page in response to XHR response (success or failure), so in my actionCreator, I will have code like this
APIManager.post(url, postData).then(function(response) {
NotificationHelper.create(<SuccessNotification />)
});
I don't know if it's correct to call something like this from action creator that renders a new component.
With stores
Another approach is to create a NotificationStore and on emitChange render the notification component.
The code will look something like this
In my App.js, the code will be
<body>
<Header />
<Fooder />
<NotificationContainer />
</body>
And then in NotificationContainer, I will do something like
onChange: function() {
this.setState({customNotification: NotificationStore.get()});
},
render: function() {
<Notification>
{this.state.customNotification}
</Notification>
}
And finally, the action creator will look something like
Dispatcher.dispatch({
actionType: 'notification',
component: <MyComponent/>
});
The problem with this approach is the additional overhead of stores. Store is not doing any meaningful thing here, it's only there just to follow the flux. From action creator, we are passing data to the store, and the component is again taking the same data from the store and rendering it. So we finish the flux cycle without really getting anything out of it.
Also, I now need to initialize NotificationContainer at the start of my app, even though I don't have any notifications at this point.
I don't really see how your problems are problems. It does exactly what it's supposed to do, and if you need to build on it later, you can easily do so. Notifications and other no-true-component-owner features are one of the best reasons to use flux in my opinion (90% of the time I don't recommend flux).
With flux the notification action creator would be responsible for creating a remove notification action after a set period of time. You can also have an x button on the notification, which when clicked creates that action, and these go to the store which removes the item if it exists, and any/all views dependant on this store update. When I say any/all I mean that the notifications component may be hidden, or there may be an alternate way to view notifications on one page of the app, or there may be a simple counter with the number of notifications anywhere in the app.
Side note: don't pass around elements in a way that they could be rendered more than once. Pass {component: SuccessNotification, props: props} instead if you need to specify the component ahead of time.
I follow the answer of FakeRainBrigand.
Sorry the self promotion here but I created a Notification component that you can use with Flux. Here you can see a issue that shows a example of usage with Alt, but the principles are the same. You add the component to a top level element on your HTML and subscribe that component to a Notification store. On your notification action creator, you can add notification with some properties like: level, position, auto-dismissible, action, etc.
Here is the component demo.
Does anybody have an idea on how I can accomplish this using Wicket?
I want to display a Wicket odal window automatically when no user activity has been detected for a certain amount of time. I'm thinking of using an AjaxSelfUpdatingBehavior in some way, but I have no clear ideas actually.
Is this possible with Wicket?
Also, you can use some js library not to catch all ajax calls and to be sure, that your user is really afk (even does not touching his mouse).
For example, see this free framework and it's demo.
And (if you using this js framework) in wicket you must handle
ifvisible.idle(function(){
Wicket.Ajax.get({u: '${callbackUrl}'})// This code will work when page goes into idle status
});
You must set ${callbackUrl} from wicket code to let js know what action to proceed in java code. It is not hard to do this. Look here.
This approach is more tricky, but if you implement this, you don't have to worry about users actions at all (he can read site's info and don't click any ajax links, but suddenly he will see modal window).
Yes you can, I use this as autologout function
public class MyTimer extends AbstractAjaxTimerBehavior {
public MyTimer(int seconds) {
this(Duration.seconds(seconds));
}
#Override
protected void onTimer(AjaxRequestTarget target) {
// show your window magic
}
}
Add this to you page (add(new MyTimer(300));) and this will be called after the number of seconds you specify. Make sure to replace the timer with a new one when doing ajax calls, or reset it.