0

I have a child state that fills up named views in the parent state (header, content). They both share the same data, however, and I don't want make a redundant second controller but seems like that's one of my only options. I could just use one view but it would then have too much markup which looks messy.

I read the docs here and the example they showed is for each view in the state to have it's own controller.

This is not ideal for my scenario. For example, ui-router says I have to do this:

.state('root.profile', {
    url: '@:slug',
    views: {
        'header': {
            templateUrl: 'app/profile/profile-header.html',
            controller: 'ProfileHeaderController as profileHeader'
        },
        'content': {
            templateUrl: 'app/profile/profile-body.html',
            controller: 'ProfileBodyController as profileBody'
        }
    }
});

.. and I'd much rather do this:

.state('root.profile', {
    url: '@:slug',
    views: {
        'header': {
            templateUrl: 'app/profile/profile-header.html'
        },
        'content': {
            templateUrl: 'app/profile/profile-body.html'
        }
    },
    controller: 'ProfileController as profile'
});

The second option works better for me because as I said they share the same data and I would rather not reproduce a lot of the same logic twice, but unfortunately it doesn't work.

I am already using a service for the one controller. I wouldn't want to have to create another service just to store one set of values to use in both controllers cause that's still not really DRY.

Is there any work-around for something like this?

3
  • This might help you. codepen.io/ahsx/pen/mDcEd Commented Dec 31, 2015 at 5:30
  • Hmm yeah it works, thanks, but I can't use it because it doesn't really follow my modular structure. I'd have to add the controller into the module file, which is no bueno :D Commented Dec 31, 2015 at 5:35
  • For better understanding, refer docs.angularjs.org/guide/controller Commented Dec 31, 2015 at 5:39

1 Answer 1

1

Considering you code examples, I don't see how this statement is false: "they share the same data and I would rather not reproduce a lot of the same logic twice".

1) they share the same data: Since you have a service, I assume the service stores the current data state, which means that the controllers do share the same data.

2) rather not reproduce a lot of the same logic twice: Your views are referencing the same controller, but different instances, which means that you don't have to reproduce any logic.

"I am already using a service for the one controller. I wouldn't want to have to create another service just to store one set of values to use in both controllers". If you would make that services a factory, which is a singleton, the same instance would be passed in to each controller that uses the factory-service.

However, I see one possible solution you could do for resolving data and defining controller as a parent to the profile state. This, by having another state between root and root.profile state. In the example below the two views (profile-body.html and profile-header.html) can now use the same instance of the ProfileController.

.state('root', { .. })
.state('root.profile', {
    abstract:true,
    controller:'ProfileController as profile',
    resolve: {
       profile:function(yourProfileDataService) {
           //Resolve profile data
       }
    }
})
.state('root.profile.view', {
    url: '@:slug',
    views: {
        'header': {
            templateUrl: 'app/profile/profile-header.html'
        },
        'content': {
            templateUrl: 'app/profile/profile-body.html'
        }
    }
});

As seen in the example, I also suggest the usage of the resolve property which resolves the data before instantiating the controller, and then injects it into the controller. Resolve docs.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the suggestion @cbass. I can't use this method because I do not want to resolve the data to the controller because of the delay. Currently doesn't work well with my setup from a UI/UX point of view. The act of placing an abstract parent state for the controller (minus the resolve), however, is a good solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.