Hi everyone !
I recently faced an issue in my personnal development and had to create a new directive to achieve it. I wanted an ngIf directive but rendering the content only once then caching it.
Here is the description of my module, any comment is appreciated has it is my first contribution :
Tested with :
Angular 5 +
Playground : https://stackblitz.com/edit/ngx-cache-if
npm : https://www.npmjs.com/package/ngx-cache-if
Why I did this :
By default ngIf diretive render the component each time you want to display it. And destroy it when you hide it. This cause the lifecycle events to trigger multiple time if you display the same content. (An async call made in ngOnInit for example).
The hidden/shown behaviors renders the element at the rendering of the parent component and hide or display it with css. This cause the lifecycle events to be triggered at the rendering of the parent view. If you have multiples components to load in the same view that can cause a large amount of operations if they are computing all at the same time instead of rendering only when needed.
What do you think about it ?
This is just my personal opinion, feel free to ignore completely.
For a long time, the first question I used to ask myself when I ran into trouble trying to do X was always “how do I make X easier?”.
Over and over again, I had the experience of making X easier and then eventually realizing that after all that, X wasn’t really what I wanted to do.
So now the first question I ask myself when I run into trouble doing X is “what am I really fundamentally trying to achieve, and might there be a better way than X?”
I think this is one of those situations. You have created a directive whose sole purpose seems to be making doing heavy things in lifecycle events less onerous. Instead, I would suggest not doing heavy things in lifecycle events. Do heavy things in response to user activity. Users expect pressing a refresh button to initiate something that might take some time; they don’t expect flipping back and forth between pages to do the same, unless absolutely necessary.
View layer components are mere windows. A window doesn’t have to do much when somebody decides to look through it, though the room inside might. So I have found that a more robust and performant way to handle this scenario is to offload all the heavy lifting onto service providers, that act as the room in the analogy.
All that I do in response to lifecycle events is subscribe and unsubscribe to
Observables exposed in service providers. When and how the underlying data behind that
Observable is fetched or changed is completely independent of what view is or isn’t looking at it, to the extent possible.
Thanks for your comment but I think you haven’t understood the goal of my work. I totally agree with you about all you said, but it is not related to my directive.
My directive is related to component rendering, and fills the gap between ngIf and [hidden] directive. I thought a lot about my problem, I have a component which loads data from a service provider, then this component handle nested components with segments. I did not want to load all my heavy nested async json from my webs ervice at first page load (hidden directive) but I did not want to load it each time either (ngIf directive).
I want the nested segment content to be loaded only one time, because, as the aim of segments, the user is able to switch between views on the same page. So when a user tap a segment the component is rendered once, calling web service only once, then if the user switch to an other segment and come back to this one there is no more loading.
Please tell me If i’m not clear enough.
I updated the github readme with gifs to explain the differences between ngIf, hidden and ngxCacheIf.
Here is an example to show the ngxCacheIf behavior :
As you can see the segment content is loaded only once, the countdown is initiated at segment rendering and does not reset when we switch the segment. Feel free to consult the other examples on the https://github.com/vlafranca/ngx-cache-if