Angular initial data load, defer directives until after initialise - javascript

I need to load some data into my angular app the first time it is loaded. The data needs to come from the server.
My app currently consists of a number of directives on a single view in an accordion. The directives are forms whose criteria needs to be met before the user can progress to the next accordion group. The first accordion group needs to use the data from the server to display to the user, there is a dependency on the data for the view.
What is the best way to inject this data in the first instance?
I could move the initial data call into the first directive but it doesn't really feel like it is 'its' job. I could create another directive to handle this load but then I would need manage the load order of the directives. I have had a look at ng-init which works well until the server call is made, during this call the directives run before it completes.
Any of the above would work for me in theory but i'm not sure that they are the best approach. What would you suggest is the best approach?
Thanks

You should use a resolve in your state, so, both views and controllers are called when the resolution is done.
have a look at this link: http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx

You can decorate your directives with ng-if attribute and, as value, pass a scope property that will indicate data load ex.

Related

Ember controllers in nested routes

i'm very confuse about how ember controller works.
I'm starting with ember and ember-cli now, and i would like to understand more about how controller works.
If i have an nested route called new, inside a events resource, i should i have:
models/event
routes/events/new
templates/events/new
What about controllers?? I just work one simple controller, or should i use controllers/events/new too?
There isn't any generator command that will create every resource for me? I need call one by one?
Thanks.
What about controllers?? I just work one simple controller, or should i use controllers/events/new too?
This mainly depends on what is your controller needs to do. If it's only the essential stuff the controller does anyways, Ember will create that controller under the hood for you and automatically bubble actions up to its parent controller.
No better place than Ember guides to read what a controller is used for:
The simplest definition is:
Controllers allow you to decorate your models with display logic.
This means that you basically use them as the main communication layer between your route and your template. Essentially, you model comes from your route, through your controller and into your template. Actions happening in the template go up to the controller and then to the route. Therefore, controller is essentially the middle layer where you user your model (and other data) to control what is shown to the user, control what a user can do, control where can they navigate etc.
However, be aware of the plan for the future:
Controllers are very much like components, so much so that in future versions of Ember, controllers will be replaced entirely with components. At the moment, components cannot be routed to, but when this changes, it will be recommended to replace all controllers with components.
This means, that right now, controller responsibility is limited to two things:
Maintaining application state based on the current route
Handling or bubbling user actions that pass through the controller layer when moving from a component to a route.
All actions triggered on a template are first looked up on the controller, if it is not handled or bubbled (by return true) in the controller, they are looked up on the route.
Therefore, controllers for your /events or events/new routes aren't necessary at all, only if you want to handle things happening on those routes right away (in a smaller scope) instead of allowing everything to bubble up to the ApplicationController.
There isn't any generator command that will create every resource for me? I need call one by one?
Yes. Since, if you don't specifically create a controller, Ember just generates one for you behind the scenes. You need to specify where you want to handle things yourself.
You should visit the link I gave above (or here it is again) to the Ember guides that have many more examples in much more detail.

Correct way to access a function in a scope

I'm using user contributed modules that I am trying not to edit so that upgrades are nice and easy.
I'm attempting to allow a user to browse to a CSV File on the local filesystem, parse it and display it in a dynamic table. To do this I'm utilizing PapaParse, ui.grid and angularFileUpload.
The problem I'm running into is that they all work at different levels at the hierarchy.
angularFileUpload is nice an easy - it calls a function in my controller (using controllerAs syntax). That function then runs a PapaParse function to convert the CSV file to a JSON Object (all working so far).
The problem I have is that ui.grid works on the $scope object since it's a attribute directive and doesn't support watchers to monitor for changes to a variable (you have to call a function on data update to re-bind the data).
So the question is, from within my controller whats the correct/recommended way to communicate with an external directive without editing the directive to listen to messages.
ui.grid should bind to changes of its associated data. Therefore you should only change your local $scope, to which the grid is also bound, and everything works fine.
As you mentioned, directives do not listen to messages, but that's is also not how Angular works. Angular forces data-binding, so by binding a field into the directive, the component should take care of updating its presentation, as soon as you change the model you bound it to.
Unfortunately, ui.grid does not adhere to this convention. Therefore you have to render the grid as soon as you user's data is there (inside the function that is called after opening the file or via $watch). This can for example be done via ngIf, where the child directive is only loaded when a field is true. When the user switches between two CSVs, you could set the value to false, load the data in your model and set it to true again. Be sure that there is one digest cycle (e.g. via $timeout) in between so that your change affects the UI.

Angular - Lazy loading an entire page from CMS

I'm attempting to build an angular app that is driven by the CaaS/CMS known as Prismic.io.
Phase one of this project will be a straight forward content-silo (CMS-managed), and phase two will add on more complex web app components. Knowing this, I've decided that Angular would be my best bet, but I'm struggling to think of a good solution to have all of the content lazy-loaded from the Prismic API.
One solution I've decided to explore would be to have a standardized $scope variable, let's call it $scope.loaded. Each controller will do what it must to query my Prismic service for its respective content, and once it's completed, it would set $scope.loaded = true.
The part I'm stuck on with this approach is how exactly to display the page while all of these components are loading. The easiest way would be to include ng-if directives that reference this loaded value, but I feel like there'd be a massive flash of unstyled content. And yes I could use spinners, but the idea of having 90% of the page covered in spinners seems chintzy.
Then I got to wondering: what if I pull up a loading screen for the app until all controllers' $scope.loaded values are truthy? In that case, how would I know which controllers are currently active on the page and reference their respective scopes?
(If you have comments about why this approach is bad, I'd love to hear them as replies rather than answers. I imagine this could create too many http request, for example).
A couple of options here:
Have you looked at ngCloak to see if will help you here with the flicker problem? https://docs.angularjs.org/api/ng/directive/ngCloak.
If you're using jquery, you could have a global spinner that works on concurrent ajax requests http://api.jquery.com/category/ajax/global-ajax-event-handlers/.
Or have a look at something like this global angular spinner https://github.com/monterail/angular-global-spinner/tree/master/src.
If none of these work, you could always create an array on the root scope where each controller/directive registers itself and sets its loading flag. Then add a watch to that variable to see when all components in that array are finished loading.

Initialize Angular $scope on initial load

I would like to init the user session with some data. On loading the main outer controller (I have a "global" controller that is run for the entire app and individual controllers for each state/route) I currently check if the local session data is empty and, if so, fetch from server and return a promise.
The issue that I have is that I use directives which need this session data. Currently they run before the scope is populated. I need a solution that does not involve modifying all the directives to use promises/callbacks/etc.
On researching this I found many requests but no viable solutions. I am using UI router and looked at the grandfather state idea but that just seems to act as a master resolve that still needs to be addressed in each controller.
I have also looked at manually bootstrapping but I need to populate the scope and I don't see how to do that from angular.element.
I should add that this needs to a pause the Angular process until loading. I see suggestions for global configuration but not sure how do pause besides deferring bootstrapping.
Suggestions?
Can you do your work in main module's .run method. and set whatever you want at $rootScope.
That way it will be visible everywhere.
Angular Modules
You can use value receipe, ngtutorial.com/learn/value
You can write your provider which will perform you some functionality.
You can take a look here - Documentation for providers how to do it. From the link you can see:
You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts.
By the way, if you want to access scope from angular.element = you can use:
angular.element(<yourElement>).scope()

Application sending JSON on demand, not on creation (Ext-JS 4)

When I start my application, my computer loads it 15 seconds. It loads a whole bunch of grids and things that I want to load dynamically.
What do I have to do if I want for those grids to be loaded "on demand"? Do I have to load controllers dynamically or just the grids? And how?
Thank you. :)
That depends on your application structure and the configuration of the stores. Following are some tweaks that you may apply:
remove autoLoad from the stores and keep in mind that you now need to care about loading if you don't apply paging or filtering. Why? Any store that you place in your controller store array will be instantiated as soon as the controller get instantiated, which is great but cause the load of the store if autoLoad is true. Based on the implementation the store will get loaded again for example a pagingToolbar will defiantly again fire a load so the first could be spared.
apply a sort of lazy controller loading. Meaning; only apply that controllers into the application controller array that you need right at the start. Load any other controller only when you need it by calling this.application.getController('ControllerName') within a controller or directly on the application controller. This will give you the conrtoller instance and init the controller (this is quite new, so I dunno since when this happens automatically. I check 4.1.3). Anyway, the lazy controller initialization will defer all Ext.Loader request for each of these controllers till the controller get initialized, so this will help you most I guess.
It looks to me as if those scripts are being loaded by the ExtJS loader itself, I'd imagine it's loading what it thinks it needs due to the structure of the page based on the settings provided.
Have a read over the loader docs to get a feel for what it's doing and why:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.Loader

Categories

Resources