Default Content before Route Resolution - angularjs

I'm re-working a website that has a very nested interface requiring several child views. Think of a shopping site, with paging, results and filters. What I'd like to do is render default content for said children views while the results are being resolved from the back-end. However, I can't find a way to insert default content past the first <ui-view>, which of course, makes sense.
To get around this, we are currently using $broadcast in the child state controllers. We moved the resolution out of the resolve event into the controller, which is working, but requires us to make all of our directives use $broadcast as well, or they don't work since the data isn't loaded before they are. It also seems like a very inelegant solution to the issue.
What's weird, is that when I move the resolve function into a child view, neither the parent nor it's siblings views load before the results child view loads. I can't understand that whereas I can understand children views not loading before the parent is resolved.
Is there a way we can work around this? Building in broadcasting into all aspects of our code base seems like an extremely poor practice. Is there a way to show children default content before the parent is resolved, or even render child states' views before their controllers are instantiated?

Use ng-cloak class:
https://docs.angularjs.org/api/ng/directive/ngCloak
The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.

Related

What is the difference $scope.$parent vs $broadcast?

What is the difference between $scope.$parent and $broadcast?
Everything is different. They're not related at all. Two completely different things - not even the same JavaScript type.
$scope.$parent is a reference to the parent scope object, while $broadcast is a function to broadcast an event.
Basically im writing a common layout.
Inside common layout developer will write his code using ui-view.The common layout will have button events when fired it should change the state of ui-view which is nested.
For this if i use components i think i cant achieve because
Top-framwrok(buttons,titles e.t.c)
Body-developer-this part is an ui-view
Bottom-framwork(border ending and some styles)
So for framwork i will have controller
So when firing any change in framework should trigger developer template also.

Working with ui-views during ui router state change

I am using UI router in an angular application where basic animations of views using ng-enter(-active) and ng-leave(-active) classes are not enough. I have already used $stateChangeStart event in an app before to scroll up before the statechange but I would like to work with the ui-views even more.
Therefore I tried to find out how the statechange process affects ui-view elements in DOM, but somehow I can't find what I am looking for.
The process I researched fires events in following order: stateChangeStart > viewContentLoading > stateChangeSuccess > viewContentLoaded. Unfortunately when I look at the DOM (using Chome dev console), only during the last breakpoint (viewContentLoaded) there are both ui-views in DOM (the "fromState ui-view" and the "toState ui-view").
I've been thinking of fading the former ui-view element, doing some other stuff and then fading the new ui-view element in so I was looking for an event where only the former ui-view exists, then both and then only the new. This way it seems to me that I should perform all the animations inside the viewContentLoaded callback which seems inappropriate.
Am I missing something in the whole concept or is there another events or approaches to this? Thanks in advance for any hints or links...

AngularJS: directive timing issue when using Angular routing

My application uses two AngularJS directives: a parent directive that contains multiple instances of a child directive. The rendering of HTML by the child directives is dependent on the width of the containing element associated with the parent directive, so the child directive must query the parent (by calling a method on its controller) to discover this width.
This implementation works fine when used in a static page, but it breaks when used as part of a single-page application that employs Angular's routing mechanism.
Specifically, with routing active, the first time the page is loaded, the HTML renders correctly, but when the page content is updated to reflect different model data, the rendering breaks. This only occurs when the width of the containing element is 100%. If it is set to a fixed width, everything works as expected.
Debugging the issue has shown me that the width of the containing parent element is not valid at the time that the child directives are rendered, so I assume I am doing things in the wrong sequence or failing to follow some aspect of Angular best practice that deals with this kind of timing gotcha.
Is there an event that my directives need to wait for before rendering?
Thanks, in advance.
Tim
If i am understanding correctly you are have few child directives that has a width dependency on the parent directive. There are events that you can try on such as $broadcast where the parent directive sends a notification to its children.Once you receive that then you can use $on event and can your child directives.
I know i am not much constructive in my answer but yes if you have built such a dependency.

how to prevent AngularJs from having old view and new view on dom when route changes

I am using a directive "slideable" which creates a slideout area and has a toggle. This code that was not written by me but it demonstrates a larger issue for me. When I changing views (most commonly /user/:id type), slideable is a directive used on the template. The directive searches for an element during its link function and binds a click event. The issue is that when I am changing routes and the new view ( same type but different id ) is being loaded the directive is re-binding to the old view. If I stop the browser in chrome during the link then I will see two ng-views on the dom and the issue is it binds to the one that is leaving.
I also have other issues that appear to be related to this phenomenon. Is it normal that the old view would still be on the dom while the new view is being formulated?? Why wouldnt the old-view be destroyed before the new one is rendered? How do I get around this issue in a directive like this?
Thanks.
I am looking to understand conceptually what is happening. I already modified the directive to select the latest view and to appropriately search and bind to the correct element. But I am a bit perplexed as to why there would be a state where both co-exist on the dom.
One definitive reason why the old HTML fragment is briefly present along with the new one is to support animation of transitions from the old to the new. Take a look at the ngView documentation and you'll see an example of an animated transition, and it'll be clear that this is not a bug or a design flaw.
Usually when someone has problems with binding to the right element or element's event, it's because they are selecting the element without limiting the scope of the selector to the HTML fragment being added or updated, or trying to target parts of the DOM outside of the directive. So that's the first place to check, that the directive is doing things right, but like I said we'll need code to check on that.

angular - reusable dialogs

I need to build a dialog to be used with any item on a list of items. The dialog is pretty much the same regardless of the item except for the values of the fields which are obviously item dependent.
The directive I am building is reading the template from a file, compiles it with $compile and then binds (links) it to the scope of the item. The result of the binding is a DOM tree. To make the dialog visible I need to append this tree to some element in the existing DOM. The nature of my dialog is such that it makes sense to append it directly to the body tag. The dialog will be used many times in combination with different items on the list
So here is my question: How much of this process (compile, bind, append) can be done in advance? I certainly can run compile once. I can also bind the compilation result to the $rootscope and append (hidden) it to the body tag. This way I can later just turn on visibility and show the dialog.
But if it is already bound and attached to DOM, is it kosher to re-bind it to some other scope, if so - what's the right way to do it? Another question is is it even worth it? might be just re-insert it every time it is needed?
If you're only ever going to display one dialog like that at a time and you will use it frequently, you don't have to re-bind it to another scope, just change the data on the scope. Something like this:
Create a service for your dialog
Create the directive and inject your service into it. When the linking function executes, pass something like $scope.dialogData to the service so that the service can update the data.
Create a controller that gets the service injected. Set the dialog data through the service to display the dialog. Since you're modifying data in your controller that's on the directives scope, Angular notices that and updates your dialog.
Add ng-show on your dialogs wrapper to make it simple to implement open()/close() methods on your service.
Now you have a dialog that can be used from anywhere in your system, and you're just re-using the same directive without having to mess with the DOM or compilation.
This is indeed excellent question and I'm happy to see that more and more people are starting to approach dialogs as services.
Regarding your particular questions, here are some of my thoughts:
You can "cache" linking function (that is - function that is returned from the $compile call) and then call this function as needed (passing in scope variables).
Instead of inserting (hidden) compiled element you could only attach it on demand, when a dialog gets opened. On top of this I would rather attach modal element to the $rootElement instead of <body> just not to touch DOM elements above where ng-app was defined. Just not to touch parts of the DOM that AngularJS is not controlling.
IMO dialogs are really close to AngularJS routes (as they provide different "views") and as such it would be very nice to have ability to resolve promises before modal is shown (as with routes).
In fact there are number of things to consider when designing a good, generic dialog service and I hope that those advice, alongside with excellent input provided by others, will get you started. But this all is a bit theoretical so if you are looking at the implementation of what was discussed here you can have a look at this implementation. ($dialog service from http://angular-ui.github.com/bootstrap/ - it is fully customizable so can be used with CSS other than Bootstrap's. Documentation here).
It can be seen in action in this plunk: http://plnkr.co/edit/PG0iHG?p=preview
Excellent question I think. You're wondering if one can "hot swap" the scope of an element. I don't know if there's a way to do that, or even if there is, if that's the Angular way. I take it you looked at how ng-view works to get as far as you've gotten?
My advice is to do the $compile once, keep the result, the link or transclusion function or whatever it's called in Angular parlance, around somewhere. And call it for each needed instance of the dialog.

Resources