-
Notifications
You must be signed in to change notification settings - Fork 3k
feat($state): "independent" (child) state #1282
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
Conversation
e3f1736
to
e6ad562
Compare
"independent" states must have defined parents (besides abstract "root") Prevent "independent" child state from rendering parent's template, but inherits everything as usual Forces state reload (render parent's views) when coming back from independent child state
e6ad562
to
c29c25c
Compare
I don't totally understand the use case / intent of this. Can you put up a plunkr with a minimal example? (I realize you updated the sample, but that doesn't really make the need clear). |
@nateabele Hello there, I put up a gh-page for you: http://gugiserman.github.io/ui-router-independent-demo/ Just the obvious, really. Since I don't have any more time today, perhaps even for the rest of this week, to work on this, I couldn't reproduce the exact (far more complex) problem we had here in the company I'm currently working at. The point is to prevent repeating URLs and Resolves in states that should follow this kind of hierarchy (maybe for REST purposes, whatever), but simply are not designed to share the same screen/layout, and manually hiding/showing based on listeners to $stateChanges just feels dirty (to me). Feels not convincing enough, man :( But hey, thanks for your attention anyways! |
@gugiserman Okay, your follow-up description actually helps a lot, thanks for that. I'll try to review the code and your example further in the next day or two. |
(Should be a) Parent state: $stateProvider
.state 'orders',
url: '/orders',
controller: 'OrdersController'
resolve:
orders: (OrderService) -> OrderService.getOrders() _(Should be a) "Child state" - Before: (If you set it's parent, you have to deal with both views being rendered in the same screen or manually hiding each other based on $state.current and change events)_ .state 'order',
url: '/orders/:id'
controller: 'OrderController'
resolve:
order: (OrderService, $stateParams) ->
OrderService.getOrder($stateParams.id) _Actually child state - After:_ .state 'order',
parent: 'orders'
independent: true
url: '/:id',
controller: 'OrderController'
resolve:
detail: ($stateParams, orders) ->
return order for order in orders when order.id is $stateParams.id I mean, even for 'DRY' reasons, besides the fact that these state's views were not supposed to share the screen or something like that. @nateabele Well, sorry for bothering again, thanks man! PS I do believe there's a better way of handling this, so we can discard the need to name the view of the "independent child" state. |
Interesting, I came across what I think is this same scenario at work and wrote a directive. I put this directive on an element I want hidden (or shown) when a nested state is activated. I wrote this because I am sharing templates between states, so something like @gugiserman Is this the same use case as you are describing?
|
@christopherthielen Yeah! Just the behavior I was looking for, man. Nice. I'm currently switching (with ng-show) the elements in the worst possible way, I guess. Which is something like But it became a need for other projects and other states/pages really fast, and it would turn into a monster :p Your directive is a pretty sweet solution, tho. I will probably do something really similar for now. Thanks! I hated to trigger a state reload (in my fork) when returning from it's child but couldn't find a way that wouldn't be aggressive. Another thought I had is that if trying to access directly the child state, there would be no need to append/render it's parent's elements into the DOM at first, nor watch for it's bindings in the template, but I do have to inherit data. |
I don't think this is a good solution. The entire level of complication is just so that you can re-occupy the same $stateProvider
.state 'orders',
url: '/orders',
controller: 'OrdersController'
resolve:
orders: (OrderService) -> OrderService.getOrders()
.state 'orders.order',
url: '/:id',
views:
'@^' # or the equivalent like '@orders' or '@dashboard'
controller: 'OrderController'
templateUrl: 'order.html'
resolve:
order: (orders, $stateParams) -> orders[$stateParams.id] Alternatively, you can simply create a $stateProvider
.state 'orders',
url: '/orders',
abstract: true
template: '<ui-view>'
resolve:
orders: (OrderService) -> OrderService.getOrders()
.state 'orders.list',
controller: 'OrdersController'
.state 'orders.view',
url: '/:id',
controller: 'OrderController'
templateUrl: 'order.html'
resolve:
order: (orders, $stateParams) -> orders[$stateParams.id] |
@gugiserman @christopherthielen I feel you guys are not leveraging view overriding properly by resorting to display toggling. There is massive power and versatility to view overriding that makes it easier to refactor later. |
@ProLoser you're absolutely right. Now I feel stupid. :) |
@christopherthielen cool now that I have second-hand confirmation I'm going to close this. I would instead like to see abstract defaults implemented which I think will solve far more use-cases in the long run! |
@christopherthielen can you confirm if it's possible to use relative paths for view definitions? Like is |
@ProLoser you can't do that right now, afaik. Also, I'll have to check how I used those directives. I might be toggling only one or two ui elements, I don't recall offhand. |
@christopherthielen honestly there are so many far more important things to do I'm just going to forget about it. |
@ProLoser thanks, man! |
If state parent's defined, "independent" property can be set and won't render nor keep it's parent's view(s)/templates (as long it's own ui-view(s) is outside of it's parent's, of course). But inherits everything else, as usual.