-
Notifications
You must be signed in to change notification settings - Fork 3k
Multiple parents for a state #384
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
Comments
you could create a directive for that? |
I guess with todays ui-router I would reuse templates and controllers in each place... and put my own service on top that knows how to define the same state specs in multiple places. Having different parents will have an impact on the context (e.g. inherited state params) one way or the other so they really arent the same states even if theyre only spec'ed out once. |
It actually is a directive now, but it's like a modal with a form in it. I thought it would be cool if you could use a state change to trigger the modal. |
This is for the login form thing? I don't think adding an extra child to every possible state makes sense here. The approach I would take is to listen for |
ditto, except I might have the service that does the checking be thing that does the listening. No reason that a service can't listen to $rootScope events. I actually create one service to wrap all the state events and to deal with managing transitions (I call it transitions) -- it does things like helping the app avoid trying to supercede transitions accidentally. It emits its own events to the rootScope. Another service manages session-releated stuff -- it listens to events from transitions and decides whether to interject itself to prompt a login. |
Lets say it's a notes modal to add notes to this object I'm on.
|
Well, there's an argument to be made for keeping modal's out of states altogether... or there's the $dialog sample technique, which uses onEnter to launch a modal. https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-open-a-dialogmodal-at-a-certain-state -- which still doesn't have the modal as its own state, but uses a state to get it going. Thinking out loud: seems like it would be great to have a built-in, easy to use way of transferring state to a modal -- such a state would be top-level, thus not needing a container template in which to live. |
So, this is something that I brought up in the initial design phase, and something that @ksperling has referred to indirectly, with respect to redesigning But I have no idea what that would look like. |
I think independent state trees would be great -- because it would also be a helpful step toward portal-like/component support. Would it be possible and useful to support independent state trees that are so independent that they are not related to each other (except by virtue of the application code gluing them together)? |
Actually I think I created a redundant issue with #953 however it would be a far simpler approach. If a sate could define an array of children states (and multiple states could specify the same child) it would be perfect. Each instance would be isolated from each other however. |
I'm having this exact same issue and the possible solution you talked about would be perfect ! |
To reiterate a little... There may be times when you have a two parent routes, say, /new & /:id but either way we want the child states of /new to be called when referencing /:id... /new/childA Perhaps a "parents" array in the config will do -- OR -- a wildcard in the parent-namespace: .state('{instance}', ...) // handles both, /new -- AND -- /:id ... So that routing to any "/childA" manifests the childA state -- even if that is the only component in the route; in other terms: .state('{REGARDLESS}.childA', ...) I know there are other ways to get around this -- for instance -- just using a wildcard in the { url: '...' }, but in many cases this has not been the MOST-desired effect as you may want to explicate certain routes. ... However, I've been designing frameworks for a while -- but I'm still a little new to ui-router; hope I'm not speaking out of my hat. |
@ProLoser I believe @nateabele has some thoughts on re-using state trees, to be tackled after the v1.0.0 rewrite |
FWIW, this solution worked for me since I only had two parent states that should both be able to access a child state: #1323 (comment) |
the only possible way of doing this at the moment, is to do things "off" angular, like dynamically creating a module. I created a reusable "login" module that could be used in admin, buy and user profile pages by wrapping the export function init(namespace: string){
angular.module('Login', [
'ui.router',
'User',
'Resources'
]).config(['$stateProvider', function($stateProvider) {
$stateProvider.state('login.register', {
views:{
'login': {
templateUrl: '/templates/shared/login-register.html'
}
}
});
$stateProvider.state('login.do', {
views:{
'login': {
templateUrl: '/templates/shared/login-do.html'
}
}
});
$stateProvider.state('login.forgot', {
views:{
'login': {
templateUrl: '/templates/shared/login-forgot.html'
}
}
});
$stateProvider.state('login', {
// this act as an abstract, the states are always set to either login.forgot, login.do or login.register
parent: namespace, // this is the trick
templateUrl: '/templates/shared/login.html', // has a <div ui-view="login"></div> along with markup
controller: Controllers.Login,
controllerAs: 'login'
});
}]);
} this way I can still use "login.do" and "login.forgot" without having to resource to namespaced state names, like "buy.login.do" or "admin.login.forgot". constructing the module is straight forward: import Login = require('../shared/login');
Login.init('buy');
//Login.init('admin');
//Login.init('user');
angular.module('Base', [
'Login'
]).config(['$stateProvider', ($stateProvider) => {
$stateProvider.state('buy', {
// the parent
});
}]); |
@pocesar That's a nice solution. I think you might be able to improve it by creating the state inside a constant function. That function can then be injected into the config calls. For example, angular.module('myApp').constant('loginDialog', function ($stateProvider, parent) {
$stateProvider.state('login', {
parent: parent,
url: '/login'
});
})
.config(['$stateProvider', 'loginDialog', function($stateProvider, loginDialog) {
loginDialog($stateProvider, 'buy');
loginDialog($stateProivder, 'admin');
loginDialog($stateProvider, 'user');
}]); |
Does that work? That generates non-unique state names. You essentially have multiple states in your application called |
Good point. Concatenating the parent into the state name should solve that. angular.module('myApp').constant('loginDialog', function ($stateProvider, parent) {
$stateProvider.state(parent + '.login', {
url: '/login'
});
})
.config(['$stateProvider', 'loginDialog', function($stateProvider, loginDialog) {
loginDialog($stateProvider, 'buy');
loginDialog($stateProivder, 'admin');
loginDialog($stateProvider, 'user');
}]); |
@ProLoser the point was to be able to use |
@pocesar I actually am not so sure that makes sense after I thought about it. If you only have 1 module running at a time, why throw it underneath x module? Why not just make it a top-level state? |
@ProLoser inheritance plus nested views unrelated to the login, but can still use login related stuff |
Honestly that is starting to sound like a directive or something. I'd be curious to see your setup. Login is sort of a weak example of this design pattern honestly. |
+1 (modal states) |
@ProLoser can this be closed? |
@eddiemonge uh i don't know, up to you if you're leading the project. I am not super present. I can always reopen if the latest version isn't sufficient. |
Hi, I have a user case that maybe rellevant to this scenario: We have a group of products that are editable with a specific state. Actually I'm working on how this can be achieved, but @mfoody solutions seems the best. I'm just learning how ui-router works, so if there's an alternative and easier solution to this, please tell me. :) |
It would be great if we have a state that can be appended to any state, haven't thought much though on its implication and detail. But I think it would greatly help |
Check this |
This is more of an RFC.
Lets say I have a child state I want to use in multiple areas of my app. Or perhaps it's more like a mixin, etc. How would you go about doing this? Should I define multiple parent states, or what?
The text was updated successfully, but these errors were encountered: