Skip to content

Feature req: access to sub-view from a controller #1259

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
marcghorayeb opened this issue Aug 7, 2014 · 14 comments
Closed

Feature req: access to sub-view from a controller #1259

marcghorayeb opened this issue Aug 7, 2014 · 14 comments

Comments

@marcghorayeb
Copy link

Hello,

I was wondering if this was possible.

Say I have a state defined like this:

views: {
            '@layout': {
                templateUrl: 'partials/home.html',
                controller: 'HomeController'
            },
            'firstSection@home': {
                templateUrl: 'partials/home/A.html',
                controller: 'AController'
            },
            'secondSection@home': {
                templateUrl: 'partials/home/A.html',
                controller: 'AController'
            }
        }

I have basically two "nearly" identical sections on a webpage that have the same template + controller.
For the sake of it, think of a form section that is visible at 2 areas, but with different behaviours. If I have submit from the first section, I'd like to redirect to the first section, if not, to the second.

Knowing this, I stupidly thought that I could add a data param to the view, and check it in the controller.

views: {
            '@layout': {
                templateUrl: 'partials/home.html',
                controller: 'HomeController'
            },
            'firstSection@home': {
                templateUrl: 'partials/home/A.html',
                controller: 'AController',
                data: { section: 1 }
            },
            'secondSection@home': {
                templateUrl: 'partials/home/A.html',
                controller: 'AController',
                data: { section: 2 }
            }
        }

However, there is now way to determine (to my knowledge) which view a controller is associated to with the $state service.

My workaround has been to create sub template for both section with an ng-include of the A.html and have a ng-init = "section = X;" so that a new scope is created for each section, but it seems kind of hacky/redundant, if only similar to $stateParams, there could be some kind of a $viewData service?

Any thoughts?

Thanks!

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

This doesn't make sense. If you have an AController and a BController why not just do $scope.section = 'A' or something in each controller and use that in the view? This is overcomplicating things.

@marcghorayeb
Copy link
Author

My bad, copy paste error, both controllers are the same.

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

Personally, I've done stuff like this. I moved as much redundant logic into a service, and made the controllers contain the only distinguishable code.

@marcghorayeb
Copy link
Author

Let me go into more details on the why of this :)
AController will basically be handling a form submit. When the form is submitted, a $state.go is called to the same exact page, but with different parameters in the url (query params).
When the page is loaded, based on if it was called from the first section or the second section, the view will be scrolled towards the correct form.
I need the state to change. For one, the URL has to be different, and I cannot just load some data as there are certain resolve logic that is taken care of on the state change that need to be executed again.
What do you think ?

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

Let me ask you this, is it a big problem to create AController and BController instead of reusing AController?

@marcghorayeb
Copy link
Author

Well, that's the same as doing an intermediate template with a different scope which I ended up doing in the end. I still think it to be kind of weird when both logic are the same and easily avoidable if the controller knew which view object instantiated it in the $state config.

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

It's so odd, like the entire problem only exists because you have 2 controllers on the same view. Any other combination and there wouldn't be a problem. I don't like having arbitrary data, I feel like if the controller could introspect which view it's on you could figure out the rest.

@marcghorayeb
Copy link
Author

Not same view, same state but yup, if the controller could introspect the view that instantiated it, it would be easy :)

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

Does ui-router handle controller-as-scopeName?

@marcghorayeb
Copy link
Author

hmm, I think so. Do you think that could help out ? I'll dig into it !

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

You could do 'Controller as AController' and 'Controller as BController' and then inside the controller have if $scope.AController === this ...

@marcghorayeb
Copy link
Author

@ProLoser Works like a charm ! 👍
You just have to make sure that you're not checking that value in controller function itself but at least after $stateChangeSuccess (come to think of it, that's normal ;) )
Thanks a lot ! 🍻

@ProLoser
Copy link
Member

ProLoser commented Aug 8, 2014

What? No I was exactly referring to doing it from inside the controller, but whatever works.

Glad we could knock one more bug off the list.

@marcghorayeb
Copy link
Author

Yes it's inside the controller, but i mean, you have to wait for the $stateChangeSuccess to have a value associated with the controller alias:

app.controller('AController', function ($scope) {
   console.log($scope.alias, $scope.alias === this);
})

This outputs null and false.

app.controller('AController', function ($scope) {
  var self = this;
   $scope.$on('$stateChangeSuccess', function () {
     console.log($scope.alias, $scope.alias === self);
   })
})

This correctly works :)

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

2 participants