Skip to content

Order of resolves and rendering #459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
matt-way opened this issue Sep 23, 2013 · 19 comments
Closed

Order of resolves and rendering #459

matt-way opened this issue Sep 23, 2013 · 19 comments

Comments

@matt-way
Copy link

I have a situation where I have a parent state which is like a toolbar/frame, and a child state which contains some content, however the content requires a resolve to complete. I thought ui-router would elegantly load the parent controller before needing to complete the child resolve.

In other words, the app currently goes: child_resolve->parent_ctrl/view->child_ctrl/view, when I believe it should go: parent_ctrl/view->child_resolve->child_ctrl/view. Is there any reason why it doesn't occur in this fashion? Any possible work around?

@laurelnaiad
Copy link

Are you using 0.2.0? #73

@matt-way
Copy link
Author

Yeah, 0.2.0. #73 seems like a different issue.

@laurelnaiad
Copy link

Sorry -- I didn't recognize the difference.

@matt-way
Copy link
Author

Imagine you have your view setup like this

<div ui-view="">
    <div ui-view=""></div>
</div>

and then you had two states: app_parent & app_parent.app_child. In this case app_parent.app_child has a resolve. What I want, is for the app_parent template and controller to load before the child resolve completes.

@laurelnaiad
Copy link

The order of resolves should be handled in #73, if I understand correctly.]

If that's the case then it would seem that whatever is happening in your controllers could be made to happen in the order you're describing. Also, perhaps you could write your controllers so that they don't depend directly on each other but each depend on the resolved values to which they have access. But again, maybe I'm not understanding the issue.

@laurelnaiad
Copy link

Just curious -- are you by any chance using "controller as" syntax?

@matt-way
Copy link
Author

#73 is about resolve orders (i.e. having both parent and child resolves), which is something I'm not talking about. I only have a single resolve in the child. The problem is that the parent ui-view doesn't render, or instantiate the parent controller until the child resolve has completed.

I am using controller in $stateProvider.state() for both parent and child state.

@matt-way
Copy link
Author

So in other words this is what I think should happen:

state definitions:

$stateProvider.state('parent', { abstract: true, templateUrl: 'parent_template', controller: 'ParentCtrl' })
              .state('parent.child', { url: '/child', templateUrl: 'child_template', controller: 'ChildCtrl',
                     resolve: { someObj: function(myService) { return myService.getObjPromise(); }}});

Now when the app is loaded (/child), the parent_template & ParentCtrl should be loaded before the resolve of the child completes.

@laurelnaiad
Copy link

Gotcha.

@matt-way
Copy link
Author

Sweet. I think I might have some work arounds, but any ideas would be appreciated.

@laurelnaiad
Copy link

The work around I can think of is not to use resolve in your child state and get its data when the controller is instantiated instead. You'd need to do some different stuff with your rendering to get the effect that I assume you're looking for.

@matt-way
Copy link
Author

Yeah thanks. That turns out to be exactly what I did. Would be nice in the future though if ui-router did work the way above.

@nateabele
Copy link
Contributor

The currently-implemented phased approach is tied into the lifecycle of state transitioning and view rendering. Breaking it for your special case is really not an option, sorry.

Honestly, it sounds like you're trying shoehorn your code into a combination of nested controllers & resolves, and trying to synchronize those in that way is actually a symptom of a deficiency in your design.

You're probably much better off extracting the whole thing out into a service that manages your asynchronous data, and can queue incoming operations against it.

@matt-way
Copy link
Author

I completely disagree that my case is "special". Others surely have use cases where rendering the parent before a child is required. The only difference here, is that one of the children needs to resolve some data before getting built. With the current ui-router design, you gain practically nothing by allowing child states to resolve, other than being able to use state params.

Please, what do you think is more useful?

  1. Parent resolves -> Child resolves -> Parent Ctrl/View is built -> Child Ctrl/View is built
  2. Parent resolves -> Parent Ctrl/View is built -> Child resolves -> Child Ctrl/View is built

@laurelnaiad
Copy link

For data i'd pass stateparams to controllers and let them load their data from services. Components are presented as spinner gifs until the promises that are resolved within the controller. You gain flexibility by not using ui-router's resolve to load data. Im glad I have the option to do it eithrr way though and neither seems broken.

@matt-way
Copy link
Author

Stu that is what I have ended up doing, and it works fine. The reason why I liked the appeal of using resolve, was because it would enforce dependence for all further possible children. With the way you have described above, any further children need to individually check the resolved state of the data for every controller.

@laurelnaiad
Copy link

If you sey up services that graciously lazy load your data for you it can feel pretty clean in the controllers.... theres something about it that feels like "extra work" but it doesn't bother me too much.

@matt-way
Copy link
Author

That's true.

@andreev-artem
Copy link

The currently-implemented phased approach means that something will be displayed only when full view's hierarchy will be resolved. Did I understand that correctly?
We can't display header, we can't display sidebar until main content will be loaded.

  1. Parent resolves -> Child resolves -> Parent Ctrl/View is built -> Child Ctrl/View is built

Is that principal position? Or it could be changed to
2) Parent resolves -> Parent Ctrl/View is built -> Child resolves -> Child Ctrl/View is built
?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants