-
Notifications
You must be signed in to change notification settings - Fork 137
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
Can't access future state children #384
Comments
You gave the name Try changing it to this:
|
@wileymarques You missed the Declaring: {
name: 'lazy.a', // child state
url: '/a',
component: LazyAComponent
} is the same as declaring: {
name: 'a', // child state
parent : 'lazy', // parent state
url: '/a',
component: LazyAComponent
} |
Yes, it's almost the same. The difference is simply the name. |
You have found the solution ? Thanks |
I'm running into the same issue. It seems that we're providing enough information in our state declarations that the URLs should be able to be generated. I wrote some tests against the To get around this I started writing my own wrapper around this using a URL registry that I would keep track of and then use the router's So I'm stuck as well. I am probably going to go back into the core ui-router code and see what I can do about flattening future states so that EDIT: |
This is a very old thread but bare with me: This is issue is to be expected for the following reason: The state is lazy loaded through future states, so when you haven't loaded the module containing the state implementations, the router that's trying to resolve the lazy-loaded state has no clue the lazy-loaded state even exists. When you're resolving the lazy state through uiSref="lazy", you will get the correct URL, as the "lazy.**" default URL is /lazy, which is the same as the "lazy" state. The module creating the URL for the "lazy" state doesn't actually know that state "lazy" exists, but it does know a future state "lazy.**" exists and just generates a URL for that state instead. This just happens to be identical to "lazy". So in short, you're right, you can't access the future state children if the module has not been loaded yet, because the router has no clue those states even exist. I'd suggest closing this issue as this is expected behavior. It does need some kind of service to be able to generate URLs for lazy loaded states though because it's inconvenient dealing with this situation. |
@roelofjan-elsinga I suppose alternatively ui-router could try to load the lazy loaded module in an attempt to resolve the url for a lazy loaded state, although that might defeat the purpose of lazy load... |
In the future state paradigm, a single placeholder state is loaded up front. This placeholder state has wildcards which match all child states (
As @roelofjan-elsinga mentions, the router doesn't know the details of the lazy states until after they have actually been lazy loaded. If the goal is to have correct URLs in links for lazy loaded states, perhaps we can eagerly provide that information to the router. A new lazy load paradigmInstead of using the future state paradigm, the lazy module can eagerly provide partial state definitions to the router. The partial definitions should be just enough to generate proper URLs. When any of those states are activated, the module code can be lazy loaded, the partial state definitions deregistered, and the full state definitions registered. The eagerly provided partial state definitions can be as simple as a state name and url. export const placeholder = { name: "placeholder", url: "/placeholder" };
export const placeholderChild = { name: "placeholder.child", url: "/child" };
export const placeholderNest = { name: "placeholder.child.nest", url: "/nest" }; This would allow the router to generate proper urls for, e.g., When the full module is lazy loaded, it can provide full state definitions, including components and resolves. It can either duplicate the
However, we would still need a hook that lazy loads the module, deregisters the partial states, and loads the lazy Our new state definition looks like: export const placeholder = {
name: "placeholder",
url: "/placeholder",
// This hack replaces the `loadChildren` with a `lazyLoad` block.
// Unlike loadChildren, lazyLoad has access to the current Transition object.
// In a future version of uirouter/angular, perhaps loadChildren would have access to the Transiton.
lazyLoad: (transition, stateObject) => {
const { stateRegistry } = transition.router;
// loadNgModule is an internal detail of the `loadChildren` implementation.
// See https://github.com/ui-router/angular/blob/master/src/statebuilders/lazyLoad.ts
const callback = loadNgModule(() => import("./placeholder.module")
.then(m => {
// Deregister the eager placeholders before loading the lazy loaded NgModule.
stateRegistry.deregister('placeholder');
return m.PlaceholderModule;
}));
return callback(transition, stateObject);
},
}; One more detail to consider... when defining the lazy half of these states, if we copy all the properties from the eager portion ( export const placeholderRoot = {
// Copy the details from the eager half
...eager.placeholder,
// Add any lazy loaded stuff
component: Lazy1Component,
// Set layLoad to undefined so we do not infinitely loop attempting to
// lazy load the root placeholder tree
lazyLoad: undefined,
}; ExampleI've created a proof of concept on stackblitz that demonstrates both paradigms (one future state tree and one eager/lazy placeholder tree) I'd like to hear your thoughts |
It does the trick i guess.
|
This issue has been automatically marked as stale because it has not had This does not mean that the issue is invalid. Valid issues Thank you for your contributions. |
Run into this myself just now 😞 Was linking to a lazy-loaded module from a root module never a use-case consideration ? |
There are two things being discussed in this issue:
To be clear: Srefs from the root module to lazy loaded modules are supported, with the caveats above. I commented with a workaround to address issue #2 |
@christopherthielen We cannot target a substate defined inside a lazy loaded state which hasn't been fetched yet.
If i have a future state with a child state :
included in this module :
lazy loaded in my main router:
referenced in the main module:
I cannot reach the
lazy.a
state from my main component:Since
lazy.a
state url is unknown when the router definition hasn't been fetched from the server,StateService.href(...)
used in the uiSref directiveupdate()
function can't return the correct href because it has no means to know it.Same thing when you manually try to reach the state with some click function calling
StateService.go(...)
:It would be nice to pass a relative or absolute url or some kind of option to the uisref to achieve this. For example in this case something like:
Thanks in advance.
The text was updated successfully, but these errors were encountered: